Update Cheatcode Printer

pull/2413/head
Alexis 8 months ago
parent 46d0cb13db
commit 7045cb82d8
No known key found for this signature in database
  1. 1
      slither/printers/all_printers.py
  2. 53
      slither/printers/summary/cheatcodes.py
  3. 66
      tests/e2e/printers/test_data/test_printer_cheatcode/README.md
  4. 14
      tests/e2e/printers/test_data/test_printer_cheatcode/src/Counter.sol
  5. 8
      tests/e2e/printers/test_data/test_printer_cheatcode/src/Vault.sol
  6. 36
      tests/e2e/printers/test_data/test_printer_cheatcode/test/Counter.t.sol
  7. 32
      tests/e2e/printers/test_data/test_printer_cheatcode/test/Vault.t.sol
  8. 15
      tests/e2e/printers/test_printers.py

@ -24,3 +24,4 @@ from .summary.when_not_paused import PrinterWhenNotPaused
from .summary.declaration import Declaration
from .functions.dominator import Dominator
from .summary.martin import Martin
from .summary.cheatcodes import CheatcodePrinter

@ -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:
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

@ -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 <your_rpc_url> --private-key <your_private_key>
```
### Cast
```shell
$ cast <subcommand>
```
### Help
# Counter
Init using :
```shell
$ forge --help
$ anvil --help
$ cast --help
forge install foundry-rs/forge-std
```

@ -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++;
}
}

@ -1,8 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract Vault {
constructor(){
}
}

@ -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);
}
}

@ -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 {
}
}

@ -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())
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"
)

Loading…
Cancel
Save