Skip to content

Commit

Permalink
Merge branch 'master' into pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dbast authored Aug 24, 2024
2 parents d3dadee + aeeb2d3 commit 851c4a5
Show file tree
Hide file tree
Showing 53 changed files with 756 additions and 295 deletions.
4 changes: 2 additions & 2 deletions .github/scripts/tool_test_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

# used to pass --cov=$path and --cov-append to pytest
if [ "$1" != "" ]; then
pytest "$1" tests/tools/read-storage/test_read_storage.py
pytest "$1" tests/tools
status_code=$?
python -m coverage report
else
pytest tests/tools/read-storage/test_read_storage.py
pytest tests/tools
status_code=$?
fi

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}

- name: Docker Build and Push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64/v8,linux/arm/v7
target: final
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pip-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ jobs:
python -m pip install .
- name: Run pip-audit
uses: pypa/gh-action-pip-audit@v1.0.8
uses: pypa/gh-action-pip-audit@v1.1.0
with:
virtual-environment: /tmp/pip-audit-env
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ jobs:
path: dist/

- name: publish
uses: pypa/gh-action-pypi-publish@v1.8.14
uses: pypa/gh-action-pypi-publish@v1.9.0

- name: sign
uses: sigstore/gh-action-sigstore-python@v2.1.1
uses: sigstore/gh-action-sigstore-python@v3.0.0
with:
inputs: ./dist/*.tar.gz ./dist/*.whl
release-signing-artifacts: true
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ FROM ubuntu:jammy AS python-wheels
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
gcc \
git \
make \
python3-dev \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
Expand Down
31 changes: 30 additions & 1 deletion scripts/ci_test_upgradability.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

### Test slither-check-upgradeability

DIR_TESTS="tests/check-upgradeability"
DIR_TESTS="tests/tools/check_upgradeability"
solc-select install "0.5.0"
solc-select use "0.5.0"

slither-check-upgradeability "$DIR_TESTS/contractV1.sol" ContractV1 --proxy-filename "$DIR_TESTS/proxy.sol" --proxy-name Proxy > test_1.txt 2>&1
Expand Down Expand Up @@ -181,6 +182,32 @@ then
exit 255
fi

slither-check-upgradeability "$DIR_TESTS/contract_initialization.sol" Contract_no_bug_reinitializer --proxy-filename "$DIR_TESTS/proxy.sol" --proxy-name Proxy > test_14.txt 2>&1
DIFF=$(diff test_14.txt "$DIR_TESTS/test_14.txt")
if [ "$DIFF" != "" ]
then
echo "slither-check-upgradeability 14 failed"
cat test_14.txt
echo ""
cat "$DIR_TESTS/test_14.txt"
echo ""
echo "$DIFF"
exit 255
fi

slither-check-upgradeability "$DIR_TESTS/contract_initialization.sol" Contract_reinitializer_V2 --new-contract-name Counter_reinitializer_V3_V4 > test_15.txt 2>&1
DIFF=$(diff test_15.txt "$DIR_TESTS/test_15.txt")
if [ "$DIFF" != "" ]
then
echo "slither-check-upgradeability 14 failed"
cat test_15.txt
echo ""
cat "$DIR_TESTS/test_15.txt"
echo ""
echo "$DIFF"
exit 255
fi

rm test_1.txt
rm test_2.txt
rm test_3.txt
Expand All @@ -194,3 +221,5 @@ rm test_10.txt
rm test_11.txt
rm test_12.txt
rm test_13.txt
rm test_14.txt
rm test_15.txt
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
description="Slither is a Solidity and Vyper static analysis framework written in Python 3.",
url="https://github.com/crytic/slither",
author="Trail of Bits",
version="0.10.3",
version="0.10.4",
packages=find_packages(),
python_requires=">=3.8",
install_requires=[
"packaging",
"prettytable>=3.3.0",
"prettytable>=3.10.2",
"pycryptodome>=3.4.6",
"crytic-compile>=0.3.7,<0.4.0",
# "crytic-compile@git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile",
"web3>=6.0.0",
"web3>=6.20.2, <7",
"eth-abi>=4.0.0",
"eth-typing>=3.0.0",
"eth-utils>=2.1.0",
Expand Down
10 changes: 2 additions & 8 deletions slither/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union


from crytic_compile import cryticparser, CryticCompile, InvalidCompilation
from crytic_compile import cryticparser, CryticCompile
from crytic_compile.platform.standard import generate_standard_export
from crytic_compile.platform.etherscan import SUPPORTED_NETWORK
from crytic_compile import compile_all, is_supported
Expand Down Expand Up @@ -93,13 +93,7 @@ def process_all(
detector_classes: List[Type[AbstractDetector]],
printer_classes: List[Type[AbstractPrinter]],
) -> Tuple[List[Slither], List[Dict], List[Output], int]:

try:
compilations = compile_all(target, **vars(args))
except InvalidCompilation:
logger.error("Unable to compile all targets.")
sys.exit(2)

compilations = compile_all(target, **vars(args))
slither_instances = []
results_detectors = []
results_printers = []
Expand Down
3 changes: 2 additions & 1 deletion slither/detectors/all_detectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,5 @@
from .statements.tautological_compare import TautologicalCompare
from .statements.return_bomb import ReturnBomb
from .functions.out_of_order_retryable import OutOfOrderRetryable
from .statements.unused_import import UnusedImport

# from .statements.unused_import import UnusedImport
2 changes: 1 addition & 1 deletion slither/detectors/attributes/incorrect_solc.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def _check_version(self, version: Tuple[str, str, str, str, str]) -> Optional[st
if op and op not in [">", ">=", "^"]:
return self.LESS_THAN_TXT
version_number = ".".join(version[2:])
if version_number in bugs_by_version:
if version_number in bugs_by_version and len(bugs_by_version[version_number]):
bugs = "\n".join([f"\t- {bug}" for bug in bugs_by_version[version_number]])
return self.BUGGY_VERSION_TXT + f"\n{bugs}"
return None
Expand Down
3 changes: 3 additions & 0 deletions slither/detectors/functions/arbitrary_send_eth.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
SolidityCall,
Transfer,
)
from slither.core.variables.state_variable import StateVariable

# pylint: disable=too-many-nested-blocks,too-many-branches
from slither.utils.output import Output
Expand Down Expand Up @@ -67,6 +68,8 @@ def arbitrary_send(func: Function) -> Union[bool, List[Node]]:
continue
if ir.call_value == SolidityVariableComposed("msg.value"):
continue
if isinstance(ir.destination, StateVariable) and ir.destination.is_immutable:
continue
if is_dependent(
ir.call_value,
SolidityVariableComposed("msg.value"),
Expand Down
2 changes: 1 addition & 1 deletion slither/detectors/functions/dead_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class DeadCode(AbstractDetector):
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code"

WIKI_TITLE = "Dead-code"
WIKI_DESCRIPTION = "Functions that are not sued."
WIKI_DESCRIPTION = "Functions that are not used."

# region wiki_exploit_scenario
WIKI_EXPLOIT_SCENARIO = """
Expand Down
4 changes: 2 additions & 2 deletions slither/printers/summary/loc.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

class LocPrinter(AbstractPrinter):
ARGUMENT = "loc"
HELP = """Count the total number lines of code (LOC), source lines of code (SLOC), \
and comment lines of code (CLOC) found in source files (SRC), dependencies (DEP), \
HELP = """Count the total number lines of code (LOC), source lines of code (SLOC),
and comment lines of code (CLOC) found in source files (SRC), dependencies (DEP),
and test files (TEST)."""

WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#loc"
Expand Down
4 changes: 2 additions & 2 deletions slither/tools/mutator/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sys
import time
from pathlib import Path
from typing import Type, List, Any, Optional
from typing import Type, List, Any, Optional, Union
from crytic_compile import cryticparser
from slither import Slither
from slither.tools.mutator.utils.testing_generated_mutant import run_test_cmd
Expand Down Expand Up @@ -116,7 +116,7 @@ def parse_args() -> argparse.Namespace:
return parser.parse_args()


def _get_mutators(mutators_list: List[str] | None) -> List[Type[AbstractMutator]]:
def _get_mutators(mutators_list: Union[List[str], None]) -> List[Type[AbstractMutator]]:
detectors_ = [getattr(all_mutators, name) for name in dir(all_mutators)]
if mutators_list is not None:
detectors = [
Expand Down
39 changes: 38 additions & 1 deletion slither/tools/mutator/mutators/AOR.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
from slither.slithir.operations import Binary, BinaryType
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator
from slither.core.variables.variable import Variable
from slither.core.expressions.unary_operation import UnaryOperation
from slither.core.expressions.call_expression import CallExpression
from slither.core.expressions.member_access import MemberAccess
from slither.core.expressions.identifier import Identifier
from slither.core.solidity_types.array_type import ArrayType

arithmetic_operators = [
BinaryType.ADDITION,
Expand All @@ -27,7 +32,39 @@ def _mutate(self) -> Dict:
ir_expression = node.expression
except: # pylint: disable=bare-except
continue
for ir in node.irs:

# Special cases handling .push and .pop on dynamic arrays.
# The IR for these operations has a binary operation due to internal conversion
# (see convert_to_push and convert_to_pop in slithir/convert.py)
# however it's not present in the source code and should not be mutated.
# pylint: disable=too-many-boolean-expressions
if (
isinstance(ir_expression, CallExpression)
and isinstance(ir_expression.called, MemberAccess)
and ir_expression.called.member_name == "pop"
and isinstance(ir_expression.called.expression, Identifier)
and isinstance(ir_expression.called.expression.value, Variable)
and isinstance(ir_expression.called.expression.value.type, ArrayType)
):
continue

# For a .push instruction we skip the last 6 IR operations
# because they are fixed based on the internal conversion to the IR
# while we need to look at the preceding instructions because
# they might contain Binary IR to be mutated.
# For example for a.push(3+x) it's correct to mutate 3+x.
irs = (
node.irs[:-6]
if isinstance(ir_expression, CallExpression)
and isinstance(ir_expression.called, MemberAccess)
and ir_expression.called.member_name == "push"
and isinstance(ir_expression.called.expression, Identifier)
and isinstance(ir_expression.called.expression.value, Variable)
and isinstance(ir_expression.called.expression.value.type, ArrayType)
else node.irs
)

for ir in irs:
if isinstance(ir, Binary) and ir.type in arithmetic_operators:
if isinstance(ir_expression, UnaryOperation):
continue
Expand Down
4 changes: 2 additions & 2 deletions slither/tools/mutator/mutators/LIR.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def _mutate(self) -> Dict: # pylint: disable=too-many-branches
literal_replacements.append(variable.type.max) # append data type max value
if str(variable.type).startswith("uint"):
literal_replacements.append("1")
elif str(variable.type).startswith("uint"):
elif str(variable.type).startswith("int"):
literal_replacements.append("-1")
# Get the string
start = variable.source_mapping.start
Expand Down Expand Up @@ -63,7 +63,7 @@ def _mutate(self) -> Dict: # pylint: disable=too-many-branches
literal_replacements.append(variable.type.max)
if str(variable.type).startswith("uint"):
literal_replacements.append("1")
elif str(variable.type).startswith("uint"):
elif str(variable.type).startswith("int"):
literal_replacements.append("-1")
start = variable.source_mapping.start
stop = start + variable.source_mapping.length
Expand Down
8 changes: 4 additions & 4 deletions slither/tools/mutator/mutators/abstract_mutator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import abc
import logging
from pathlib import Path
from typing import Optional, Dict, Tuple, List
from typing import Optional, Dict, Tuple, List, Union
from slither.core.compilation_unit import SlitherCompilationUnit
from slither.formatters.utils.patches import apply_patch, create_diff
from slither.tools.mutator.utils.testing_generated_mutant import test_patch
Expand All @@ -27,7 +27,7 @@ def __init__( # pylint: disable=too-many-arguments
testing_command: str,
testing_directory: str,
contract_instance: Contract,
solc_remappings: str | None,
solc_remappings: Union[str, None],
verbose: bool,
very_verbose: bool,
output_folder: Path,
Expand Down Expand Up @@ -81,7 +81,7 @@ def mutate(self) -> Tuple[List[int], List[int], List[int]]:
(all_patches) = self._mutate()
if "patches" not in all_patches:
logger.debug("No patches found by %s", self.NAME)
return ([0, 0, 0], [0, 0, 0], self.dont_mutate_line)
return [0, 0, 0], [0, 0, 0], self.dont_mutate_line

for file in all_patches["patches"]: # Note: This should only loop over a single file
original_txt = self.slither.source_code[file].encode("utf8")
Expand Down Expand Up @@ -146,4 +146,4 @@ def mutate(self) -> Tuple[List[int], List[int], List[int]]:
f"Found {self.uncaught_mutant_counts[2]} uncaught tweak mutants so far (out of {self.total_mutant_counts[2]} that compile)"
)

return (self.total_mutant_counts, self.uncaught_mutant_counts, self.dont_mutate_line)
return self.total_mutant_counts, self.uncaught_mutant_counts, self.dont_mutate_line
2 changes: 1 addition & 1 deletion slither/tools/mutator/utils/file_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def get_sol_file_list(codebase: Path, ignore_paths: Union[List[str], None]) -> L
# if input is folder
if codebase.is_dir():
for file_name in codebase.rglob("*.sol"):
if not any(part in ignore_paths for part in file_name.parts):
if file_name.is_file() and not any(part in ignore_paths for part in file_name.parts):
sol_file_list.append(file_name.as_posix())

return sol_file_list
7 changes: 6 additions & 1 deletion slither/tools/mutator/utils/testing_generated_mutant.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ def compile_generated_mutant(file_path: str, mappings: str) -> bool:
return False


def run_test_cmd(cmd: str, timeout: int | None, target_file: str | None, verbose: bool) -> bool:
def run_test_cmd(
cmd: str,
timeout: Union[int, None] = None,
target_file: Union[str, None] = None,
verbose: bool = False,
) -> bool:
"""
function to run codebase tests
returns: boolean whether the tests passed or not
Expand Down
1 change: 1 addition & 0 deletions slither/tools/upgradeability/checks/all_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
MissingCalls,
MultipleCalls,
InitializeTarget,
MultipleReinitializers,
)

from slither.tools.upgradeability.checks.functions_ids import IDCollision, FunctionShadowing
Expand Down
Loading

0 comments on commit 851c4a5

Please sign in to comment.