-
Notifications
You must be signed in to change notification settings - Fork 989
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2413 from crytic/printer-cheatcode
Printer cheatcode
- Loading branch information
Showing
8 changed files
with
162 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
""" | ||
Cheatcode printer | ||
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 | ||
|
||
|
||
class CheatcodePrinter(AbstractPrinter): | ||
|
||
ARGUMENT = "cheatcode" | ||
|
||
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: | ||
|
||
info: str = "" | ||
|
||
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) | ||
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\t{op.function.name} - ({node.source_mapping.to_detailed_str()})\n" | ||
f"\t\t{node.expression}\n\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 |
7 changes: 7 additions & 0 deletions
7
tests/e2e/printers/test_data/test_printer_cheatcode/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Counter | ||
|
||
Init using : | ||
|
||
```shell | ||
forge install foundry-rs/forge-std | ||
``` |
6 changes: 6 additions & 0 deletions
6
tests/e2e/printers/test_data/test_printer_cheatcode/foundry.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
14 changes: 14 additions & 0 deletions
14
tests/e2e/printers/test_data/test_printer_cheatcode/src/Counter.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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++; | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
tests/e2e/printers/test_data/test_printer_cheatcode/test/Counter.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters