From 46d0cb13dbdef2789a1094bfdf4ce22b4249ebae Mon Sep 17 00:00:00 2001 From: Alexis Date: Mon, 8 Apr 2024 14:58:30 +0200 Subject: [PATCH 1/8] Init Cheatcode printer --- slither/printers/summary/cheatcodes.py | 19 ++++++ .../test_printer_cheatcode/README.md | 66 +++++++++++++++++++ .../test_printer_cheatcode/foundry.toml | 6 ++ .../test_printer_cheatcode/src/Vault.sol | 8 +++ .../test_printer_cheatcode/test/Vault.t.sol | 32 +++++++++ tests/e2e/printers/test_printers.py | 12 ++++ 6 files changed, 143 insertions(+) create mode 100644 slither/printers/summary/cheatcodes.py create mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/README.md create mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/foundry.toml create mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol create mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol diff --git a/slither/printers/summary/cheatcodes.py b/slither/printers/summary/cheatcodes.py new file mode 100644 index 0000000000..8c84da8e65 --- /dev/null +++ b/slither/printers/summary/cheatcodes.py @@ -0,0 +1,19 @@ +""" + Cheatcode printer + + This printer prints the usage of cheatcode in the code. +""" +from slither.printers.abstract_printer import AbstractPrinter +from slither.utils import output + + +class CheatcodePrinter(AbstractPrinter): + + ARGUMENT = "cheatcode" + + HELP = """""" + + WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#cheatcode" + + def output(self, filename: str) -> output.Output: + pass diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/README.md b/tests/e2e/printers/test_data/test_printer_cheatcode/README.md new file mode 100644 index 0000000000..9265b45584 --- /dev/null +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/README.md @@ -0,0 +1,66 @@ +## Foundry + +**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** + +Foundry consists of: + +- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). +- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. +- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. +- **Chisel**: Fast, utilitarian, and verbose solidity REPL. + +## Documentation + +https://book.getfoundry.sh/ + +## Usage + +### Build + +```shell +$ forge build +``` + +### Test + +```shell +$ forge test +``` + +### Format + +```shell +$ forge fmt +``` + +### Gas Snapshots + +```shell +$ forge snapshot +``` + +### Anvil + +```shell +$ anvil +``` + +### Deploy + +```shell +$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key +``` + +### Cast + +```shell +$ cast +``` + +### Help + +```shell +$ forge --help +$ anvil --help +$ cast --help +``` diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/foundry.toml b/tests/e2e/printers/test_data/test_printer_cheatcode/foundry.toml new file mode 100644 index 0000000000..e6810b2b58 --- /dev/null +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol b/tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol new file mode 100644 index 0000000000..2aaf6653cc --- /dev/null +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +contract Vault { + constructor(){ + + } +} diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol b/tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol new file mode 100644 index 0000000000..6a598136df --- /dev/null +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import "forge-std/Test.sol"; +import "../src/Vault.sol"; + +contract VaultTest is Test { + + Vault public vault; + + address public alice = address(0x42); + + function broadcast() pure public {} + + function setUp() public { + vm.prank(alice); + vm.deal(alice, 1000 ether); + + uint256 value = 123; + + vm.warp(1641070800); + vm.roll(100); + vm.fee(25 gwei); + + // Not a cheatcode + broadcast(); + } + + function test_deal() public { + + } +} diff --git a/tests/e2e/printers/test_printers.py b/tests/e2e/printers/test_printers.py index 26429d3381..8d9c5587c5 100644 --- a/tests/e2e/printers/test_printers.py +++ b/tests/e2e/printers/test_printers.py @@ -1,4 +1,6 @@ import re +import shutil +import pytest from collections import Counter from pathlib import Path @@ -11,6 +13,9 @@ TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data" +foundry_available = shutil.which("forge") is not None +project_ready = Path(TEST_DATA_DIR, "test_printer_cheatcode/lib/forge-std").exists() + def test_inheritance_printer(solc_binary_path) -> None: solc_path = solc_binary_path("0.8.0") @@ -34,3 +39,10 @@ def test_inheritance_printer(solc_binary_path) -> None: assert counter["B -> A"] == 2 assert counter["C -> A"] == 1 + + +@pytest.mark.skipif( + not foundry_available or not project_ready, reason="requires Foundry and project setup" +) +def test_printer_cheatcode(): + slither = Slither(Path(TEST_DATA_DIR, "test_printer_cheatcode").as_posix()) \ No newline at end of file From 7045cb82d88adeaddd2c04947d7a9a315bc7b1cf Mon Sep 17 00:00:00 2001 From: Alexis Date: Mon, 8 Apr 2024 18:31:19 +0200 Subject: [PATCH 2/8] Update Cheatcode Printer --- slither/printers/all_printers.py | 1 + slither/printers/summary/cheatcodes.py | 55 ++++++++++++++- .../test_printer_cheatcode/README.md | 68 ++----------------- .../test_printer_cheatcode/src/Counter.sol | 14 ++++ .../test_printer_cheatcode/src/Vault.sol | 8 --- .../test_printer_cheatcode/test/Counter.t.sol | 36 ++++++++++ .../test_printer_cheatcode/test/Vault.t.sol | 32 --------- tests/e2e/printers/test_printers.py | 15 +++- 8 files changed, 121 insertions(+), 108 deletions(-) create mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/src/Counter.sol delete mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol create mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/test/Counter.t.sol delete mode 100644 tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol diff --git a/slither/printers/all_printers.py b/slither/printers/all_printers.py index 3edd5325b6..034578f528 100644 --- a/slither/printers/all_printers.py +++ b/slither/printers/all_printers.py @@ -24,3 +24,4 @@ from .summary.declaration import Declaration from .functions.dominator import Dominator from .summary.martin import Martin +from .summary.cheatcodes import CheatcodePrinter diff --git a/slither/printers/summary/cheatcodes.py b/slither/printers/summary/cheatcodes.py index 8c84da8e65..50dcdc1583 100644 --- a/slither/printers/summary/cheatcodes.py +++ b/slither/printers/summary/cheatcodes.py @@ -4,6 +4,7 @@ This printer prints the usage of cheatcode in the code. """ from slither.printers.abstract_printer import AbstractPrinter +from slither.slithir.operations import HighLevelCall from slither.utils import output @@ -11,9 +12,59 @@ class CheatcodePrinter(AbstractPrinter): ARGUMENT = "cheatcode" - HELP = """""" + HELP = """ + Print the usage of (Foundry) cheatcodes in the code. + For the complete list of Cheatcodes, see https://book.getfoundry.sh/cheatcodes/ + """ WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#cheatcode" def output(self, filename: str) -> output.Output: - pass + + info: str = "" + + vm = self.slither.get_contract_from_name("Vm").pop() + + for contract in self.slither.contracts_derived: + # Check that the IS_TEST variable is set. (Only works for Foundry) + is_test_var = contract.variables_as_dict.get("IS_TEST", None) + is_test = False + if is_test_var is not None: + try: + is_test = is_test_var.expression.value == "true" + except AttributeError: + pass + + if not is_test: + continue + + found_contract: bool = False + contract_info: str = "" + for func in contract.functions_declared: + function_info = f"\t{func}\n" + found_function: bool = False + for node in func.nodes: + for op in node.all_slithir_operations(): + if ( + isinstance(op, HighLevelCall) + and op.function.contract == vm + and op.function.visibility == "external" + ): + found_function = True + function_info += ( + f"\t\tL{node.source_mapping.lines}: {op.function.name}\n" + ) + + if found_function: + if found_contract is False: + contract_info = f"{contract} ({contract.source_mapping.filename.short})\n" + found_contract = True + + contract_info += function_info + + if found_contract: + info += contract_info + + self.info(info) + res = output.Output(info) + return res diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/README.md b/tests/e2e/printers/test_data/test_printer_cheatcode/README.md index 9265b45584..71bbaff380 100644 --- a/tests/e2e/printers/test_data/test_printer_cheatcode/README.md +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/README.md @@ -1,66 +1,6 @@ -## Foundry - -**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** - -Foundry consists of: - -- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). -- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. -- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. -- **Chisel**: Fast, utilitarian, and verbose solidity REPL. - -## Documentation - -https://book.getfoundry.sh/ - -## Usage - -### Build - -```shell -$ forge build -``` - -### Test - -```shell -$ forge test -``` - -### Format - -```shell -$ forge fmt -``` - -### Gas Snapshots - -```shell -$ forge snapshot -``` - -### Anvil - -```shell -$ anvil -``` - -### Deploy - -```shell -$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key -``` - -### Cast - -```shell -$ cast -``` - -### Help +# Counter +Init using : ```shell -$ forge --help -$ anvil --help -$ cast --help -``` +forge install foundry-rs/forge-std +``` \ No newline at end of file diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/src/Counter.sol b/tests/e2e/printers/test_data/test_printer_cheatcode/src/Counter.sol new file mode 100644 index 0000000000..aded7997b0 --- /dev/null +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol b/tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol deleted file mode 100644 index 2aaf6653cc..0000000000 --- a/tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -contract Vault { - constructor(){ - - } -} diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/test/Counter.t.sol b/tests/e2e/printers/test_data/test_printer_cheatcode/test/Counter.t.sol new file mode 100644 index 0000000000..529a7ce088 --- /dev/null +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/test/Counter.t.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; +import "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + address public alice = address(0x42); + address public bob = address(0x43); + + function difficulty(uint256 value) public { + // empty + } + + function setUp() public { + counter = new Counter(); + counter.setNumber(0); + + vm.deal(alice, 1 ether); + vm.deal(bob, 2 ether); + + difficulty(1); + } + + function testIncrement() public { + vm.prank(alice); + counter.increment(); + assertEq(counter.number(), 1); + + vm.prank(bob); + counter.increment(); + assertEq(counter.number(), 2); + } +} diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol b/tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol deleted file mode 100644 index 6a598136df..0000000000 --- a/tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; -import "../src/Vault.sol"; - -contract VaultTest is Test { - - Vault public vault; - - address public alice = address(0x42); - - function broadcast() pure public {} - - function setUp() public { - vm.prank(alice); - vm.deal(alice, 1000 ether); - - uint256 value = 123; - - vm.warp(1641070800); - vm.roll(100); - vm.fee(25 gwei); - - // Not a cheatcode - broadcast(); - } - - function test_deal() public { - - } -} diff --git a/tests/e2e/printers/test_printers.py b/tests/e2e/printers/test_printers.py index 8d9c5587c5..121c330351 100644 --- a/tests/e2e/printers/test_printers.py +++ b/tests/e2e/printers/test_printers.py @@ -1,14 +1,15 @@ import re import shutil -import pytest from collections import Counter from pathlib import Path +import pytest from crytic_compile import CryticCompile from crytic_compile.platform.solc_standard_json import SolcStandardJson from slither import Slither from slither.printers.inheritance.inheritance_graph import PrinterInheritanceGraph +from slither.printers.summary.cheatcodes import CheatcodePrinter TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data" @@ -45,4 +46,14 @@ def test_inheritance_printer(solc_binary_path) -> None: not foundry_available or not project_ready, reason="requires Foundry and project setup" ) def test_printer_cheatcode(): - slither = Slither(Path(TEST_DATA_DIR, "test_printer_cheatcode").as_posix()) \ No newline at end of file + slither = Slither( + Path(TEST_DATA_DIR, "test_printer_cheatcode").as_posix(), foundry_compile_all=True + ) + + printer = CheatcodePrinter(slither=slither, logger=None) + output = printer.output("cheatcode.out") + + assert ( + output + == "CounterTest (test/Counter.t.sol)\n\tsetUp\n\t\tL[21]: deal\n\t\tL[22]: deal\n\ttestIncrement\n\t\tL[28]: prank\n\t\tL[30]: assertEq\n\t\tL[32]: prank\n\t\tL[34]: assertEq\n" + ) From 7b9f543918883eaddf555d1e502c1efd2bb990b2 Mon Sep 17 00:00:00 2001 From: Alexis Date: Tue, 9 Apr 2024 09:37:29 +0200 Subject: [PATCH 3/8] Fix test --- tests/e2e/printers/test_printers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/printers/test_printers.py b/tests/e2e/printers/test_printers.py index 121c330351..1825f5d5c6 100644 --- a/tests/e2e/printers/test_printers.py +++ b/tests/e2e/printers/test_printers.py @@ -54,6 +54,6 @@ def test_printer_cheatcode(): output = printer.output("cheatcode.out") assert ( - output + output.data["description"] == "CounterTest (test/Counter.t.sol)\n\tsetUp\n\t\tL[21]: deal\n\t\tL[22]: deal\n\ttestIncrement\n\t\tL[28]: prank\n\t\tL[30]: assertEq\n\t\tL[32]: prank\n\t\tL[34]: assertEq\n" ) From 2f0f8ccb47f15470a434d5e7a2091b858e12b290 Mon Sep 17 00:00:00 2001 From: Alexis Date: Tue, 9 Apr 2024 09:38:28 +0200 Subject: [PATCH 4/8] Prevent failure when executed with a project not using `Vm` --- slither/printers/summary/cheatcodes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/slither/printers/summary/cheatcodes.py b/slither/printers/summary/cheatcodes.py index 50dcdc1583..24315a7e20 100644 --- a/slither/printers/summary/cheatcodes.py +++ b/slither/printers/summary/cheatcodes.py @@ -23,7 +23,10 @@ def output(self, filename: str) -> output.Output: info: str = "" - vm = self.slither.get_contract_from_name("Vm").pop() + try: + vm = self.slither.get_contract_from_name("Vm").pop() + except IndexError: + return output.Output("No contract named VM found") for contract in self.slither.contracts_derived: # Check that the IS_TEST variable is set. (Only works for Foundry) From b5766dc27dd86489ebfdede9f348d672f80b02a9 Mon Sep 17 00:00:00 2001 From: Alexis Date: Tue, 9 Apr 2024 09:44:43 +0200 Subject: [PATCH 5/8] Add cheatcode printer to test files --- scripts/ci_test_printers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci_test_printers.sh b/scripts/ci_test_printers.sh index 3306c134e2..d811c19f91 100755 --- a/scripts/ci_test_printers.sh +++ b/scripts/ci_test_printers.sh @@ -5,7 +5,7 @@ cd tests/e2e/solc_parsing/test_data/compile/ || exit # Do not test the evm printer,as it needs a refactoring -ALL_PRINTERS="cfg,constructor-calls,contract-summary,data-dependency,echidna,function-id,function-summary,modifiers,call-graph,halstead,human-summary,inheritance,inheritance-graph,loc,martin,slithir,slithir-ssa,vars-and-auth,require,variable-order,declaration,ck" +ALL_PRINTERS="cfg,constructor-calls,contract-summary,data-dependency,echidna,function-id,function-summary,modifiers,call-graph,halstead,human-summary,inheritance,inheritance-graph,loc,martin,slithir,slithir-ssa,vars-and-auth,require,variable-order,declaration,ck,cheatcode" # Only test 0.5.17 to limit test time for file in *0.5.17-compact.zip; do From 90373fbe6e653fb8dfc2f9b860aef69858c7d189 Mon Sep 17 00:00:00 2001 From: Alexis Date: Fri, 26 Apr 2024 13:42:53 +1100 Subject: [PATCH 6/8] Upgrade cheatcode printer --- slither/printers/summary/cheatcodes.py | 3 ++- tests/e2e/printers/test_printers.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/slither/printers/summary/cheatcodes.py b/slither/printers/summary/cheatcodes.py index 24315a7e20..857ec2da9f 100644 --- a/slither/printers/summary/cheatcodes.py +++ b/slither/printers/summary/cheatcodes.py @@ -55,7 +55,8 @@ def output(self, filename: str) -> output.Output: ): found_function = True function_info += ( - f"\t\tL{node.source_mapping.lines}: {op.function.name}\n" + f"\t\t{op.function.name} - ({node.source_mapping.to_detailed_str()})\n" + f"\t\t{node.expression}\n\n" ) if found_function: diff --git a/tests/e2e/printers/test_printers.py b/tests/e2e/printers/test_printers.py index 1825f5d5c6..c5b82b2572 100644 --- a/tests/e2e/printers/test_printers.py +++ b/tests/e2e/printers/test_printers.py @@ -51,9 +51,9 @@ def test_printer_cheatcode(): ) printer = CheatcodePrinter(slither=slither, logger=None) - output = printer.output("cheatcode.out") + output = printer.output("") assert ( output.data["description"] - == "CounterTest (test/Counter.t.sol)\n\tsetUp\n\t\tL[21]: deal\n\t\tL[22]: deal\n\ttestIncrement\n\t\tL[28]: prank\n\t\tL[30]: assertEq\n\t\tL[32]: prank\n\t\tL[34]: assertEq\n" + == "CounterTest (test/Counter.t.sol)\n\tsetUp\n\t\tdeal - (test/Counter.t.sol#21 (9 - 32)\n\t\tvm.deal(alice,1000000000000000000)\n\n\t\tdeal - (test/Counter.t.sol#22 (9 - 30)\n\t\tvm.deal(bob,2000000000000000000)\n\n\ttestIncrement\n\t\tprank - (test/Counter.t.sol#28 (9 - 24)\n\t\tvm.prank(alice)\n\n\t\tassertEq - (test/Counter.t.sol#30 (9 - 38)\n\t\tassertEq(counter.number(),1)\n\n\t\tprank - (test/Counter.t.sol#32 (9 - 22)\n\t\tvm.prank(bob)\n\n\t\tassertEq - (test/Counter.t.sol#34 (9 - 38)\n\t\tassertEq(counter.number(),2)\n\n" ) From ee46caecff72f5faebe72fe2d446013fbf6b9346 Mon Sep 17 00:00:00 2001 From: Alexis Date: Thu, 2 May 2024 07:40:56 +1100 Subject: [PATCH 7/8] Add missing blank line. --- tests/e2e/printers/test_data/test_printer_cheatcode/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e/printers/test_data/test_printer_cheatcode/README.md b/tests/e2e/printers/test_data/test_printer_cheatcode/README.md index 71bbaff380..f1a26a296c 100644 --- a/tests/e2e/printers/test_data/test_printer_cheatcode/README.md +++ b/tests/e2e/printers/test_data/test_printer_cheatcode/README.md @@ -1,6 +1,7 @@ # Counter Init using : + ```shell forge install foundry-rs/forge-std ``` \ No newline at end of file From ad9e8dda1af8fcadc2e7ff48b651c57f71da2e54 Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Wed, 2 Oct 2024 10:47:57 +0200 Subject: [PATCH 8/8] Update test_printers.py --- tests/e2e/printers/test_printers.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/e2e/printers/test_printers.py b/tests/e2e/printers/test_printers.py index 0c00a657f8..3ca536b0ac 100644 --- a/tests/e2e/printers/test_printers.py +++ b/tests/e2e/printers/test_printers.py @@ -41,6 +41,17 @@ def test_inheritance_printer(solc_binary_path) -> None: assert counter["B -> A"] == 2 assert counter["C -> A"] == 1 + # Let also test the include/exclude interface behavior + # Check that the interface is not included + assert "MyInterfaceX" not in content + + slither.include_interfaces = True + output = printer.output("test_printer.dot") + content = output.elements[0]["name"]["content"] + assert "MyInterfaceX" in content + + # Remove test generated files + Path("test_printer.dot").unlink(missing_ok=True) @pytest.mark.skipif( @@ -58,17 +69,6 @@ def test_printer_cheatcode(): output.data["description"] == "CounterTest (test/Counter.t.sol)\n\tsetUp\n\t\tdeal - (test/Counter.t.sol#21 (9 - 32)\n\t\tvm.deal(alice,1000000000000000000)\n\n\t\tdeal - (test/Counter.t.sol#22 (9 - 30)\n\t\tvm.deal(bob,2000000000000000000)\n\n\ttestIncrement\n\t\tprank - (test/Counter.t.sol#28 (9 - 24)\n\t\tvm.prank(alice)\n\n\t\tassertEq - (test/Counter.t.sol#30 (9 - 38)\n\t\tassertEq(counter.number(),1)\n\n\t\tprank - (test/Counter.t.sol#32 (9 - 22)\n\t\tvm.prank(bob)\n\n\t\tassertEq - (test/Counter.t.sol#34 (9 - 38)\n\t\tassertEq(counter.number(),2)\n\n" ) - # Let also test the include/exclude interface behavior - # Check that the interface is not included - assert "MyInterfaceX" not in content - - slither.include_interfaces = True - output = printer.output("test_printer.dot") - content = output.elements[0]["name"]["content"] - assert "MyInterfaceX" in content - - # Remove test generated files - Path("test_printer.dot").unlink(missing_ok=True) def test_slithir_printer(solc_binary_path) -> None: