-
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 #2278 from vishnuram1999/slither-mutate-upgrade
Upgraded Slither-mutate
- Loading branch information
Showing
24 changed files
with
1,403 additions
and
191 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Slither-mutate | ||
|
||
`slither-mutate` is a mutation testing tool for solidity based smart contracts. | ||
|
||
## Usage | ||
|
||
`slither-mutate <codebase> --test-cmd <test-command> <options>` | ||
|
||
To view the list of mutators available `slither-mutate --list-mutators` | ||
|
||
### CLI Interface | ||
|
||
```shell | ||
positional arguments: | ||
codebase Codebase to analyze (.sol file, project directory, ...) | ||
|
||
options: | ||
-h, --help show this help message and exit | ||
--list-mutators List available detectors | ||
--test-cmd TEST_CMD Command to run the tests for your project | ||
--test-dir TEST_DIR Tests directory | ||
--ignore-dirs IGNORE_DIRS | ||
Directories to ignore | ||
--timeout TIMEOUT Set timeout for test command (by default 30 seconds) | ||
--output-dir OUTPUT_DIR | ||
Name of output directory (by default 'mutation_campaign') | ||
--verbose output all mutants generated | ||
--mutators-to-run MUTATORS_TO_RUN | ||
mutant generators to run | ||
--contract-names CONTRACT_NAMES | ||
list of contract names you want to mutate | ||
--quick to stop full mutation if revert mutator passes | ||
``` |
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,54 @@ | ||
from typing import Dict | ||
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.expressions.unary_operation import UnaryOperation | ||
|
||
arithmetic_operators = [ | ||
BinaryType.ADDITION, | ||
BinaryType.DIVISION, | ||
BinaryType.MULTIPLICATION, | ||
BinaryType.SUBTRACTION, | ||
BinaryType.MODULO, | ||
] | ||
|
||
|
||
class AOR(AbstractMutator): # pylint: disable=too-few-public-methods | ||
NAME = "AOR" | ||
HELP = "Arithmetic operator replacement" | ||
|
||
def _mutate(self) -> Dict: | ||
result: Dict = {} | ||
for ( # pylint: disable=too-many-nested-blocks | ||
function | ||
) in self.contract.functions_and_modifiers_declared: | ||
for node in function.nodes: | ||
try: | ||
ir_expression = node.expression | ||
except: # pylint: disable=bare-except | ||
continue | ||
for ir in node.irs: | ||
if isinstance(ir, Binary) and ir.type in arithmetic_operators: | ||
if isinstance(ir_expression, UnaryOperation): | ||
continue | ||
alternative_ops = arithmetic_operators[:] | ||
alternative_ops.remove(ir.type) | ||
for op in alternative_ops: | ||
# Get the string | ||
start = node.source_mapping.start | ||
stop = start + node.source_mapping.length | ||
old_str = self.in_file_str[start:stop] | ||
line_no = node.source_mapping.lines | ||
if not line_no[0] in self.dont_mutate_line: | ||
# Replace the expression with true | ||
new_str = f"{old_str.split(ir.type.value)[0]}{op.value}{old_str.split(ir.type.value)[1]}" | ||
create_patch_with_line( | ||
result, | ||
self.in_file, | ||
start, | ||
stop, | ||
old_str, | ||
new_str, | ||
line_no[0], | ||
) | ||
return result |
Oops, something went wrong.