Skip to content

Commit 205d50a

Browse files
authored
Add summaries and additional bugfixes (#1830)
* Add summaries and additional bugfixes * Update test w.r.t bugfixes * Update namespace * Disable sonar
1 parent f61c2d4 commit 205d50a

File tree

23 files changed

+1055
-15
lines changed

23 files changed

+1055
-15
lines changed

.circleci/config.yml

+9-9
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ jobs:
7272
command: python3 -m build
7373
working_directory: /home/mythril
7474

75-
- run:
76-
name: Sonar analysis
77-
command: if [ -z "$CIRCLE_PR_NUMBER" ]; then if [ -z "$CIRCLE_TAG" ]; then
78-
sonar-scanner -Dsonar.projectKey=$SONAR_PROJECT_KEY
79-
-Dsonar.organization=$SONAR_ORGANIZATION
80-
-Dsonar.branch.name=$CIRCLE_BRANCH
81-
-Dsonar.projectBaseDir=/home/mythril -Dsonar.sources=mythril
82-
-Dsonar.host.url=$SONAR_HOST_URL -Dsonar.tests=/home/mythril/tests
83-
-Dsonar.login=$SONAR_LOGIN; fi; fi
75+
#- run:
76+
# name: Sonar analysis
77+
# command: if [ -z "$CIRCLE_PR_NUMBER" ]; then if [ -z "$CIRCLE_TAG" ]; then
78+
# sonar-scanner -Dsonar.projectKey=$SONAR_PROJECT_KEY
79+
# -Dsonar.organization=$SONAR_ORGANIZATION
80+
# -Dsonar.branch.name=$CIRCLE_BRANCH
81+
# -Dsonar.projectBaseDir=/home/mythril -Dsonar.sources=mythril
82+
# -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.tests=/home/mythril/tests
83+
# -Dsonar.login=$SONAR_LOGIN; fi; fi
8484
# - run:
8585
# name: Integration tests
8686
# command: if [ -z "$CIRCLE_PR_NUMBER" ]; then ./run-integration-tests.sh; fi

mythril/analysis/report.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""This module provides classes that make up an issue report."""
2+
import base64
23
import logging
34
import re
45
import json
@@ -10,7 +11,7 @@
1011
from eth_abi import decode_abi as decode
1112

1213
from jinja2 import PackageLoader, Environment
13-
from typing import Dict, List, Any, Optional
14+
from typing import Dict, Iterable, List, Any, Optional
1415
import hashlib
1516

1617
from mythril.laser.execution_info import ExecutionInfo
@@ -236,11 +237,28 @@ def resolve_input(data, function_name):
236237
data += "0" * (64 - len(data) % 64)
237238
try:
238239
decoded_output = decode(type_info, bytes.fromhex(data))
240+
decoded_output = tuple(
241+
convert_bytes(item) if isinstance(item, (bytes, Iterable)) else item
242+
for item in decoded_output
243+
)
239244
return decoded_output
240245
except Exception as e:
241246
return None
242247

243248

249+
def convert_bytes(item):
250+
"""
251+
Converts bytes to a serializable format. Handles nested iterables.
252+
"""
253+
if isinstance(item, bytes):
254+
return item.hex()
255+
elif isinstance(item, Iterable) and not isinstance(item, (str, bytes)):
256+
# Recursively apply convert_bytes to each item in the iterable
257+
return type(item)(convert_bytes(subitem) for subitem in item)
258+
else:
259+
return item
260+
261+
244262
class Report:
245263
"""A report containing the content of multiple issues."""
246264

mythril/analysis/symbolic.py

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
CoveragePluginBuilder,
2727
CallDepthLimitBuilder,
2828
InstructionProfilerBuilder,
29+
SymbolicSummaryPluginBuilder,
2930
)
3031
from mythril.laser.ethereum.strategy.extensions.bounded_loops import (
3132
BoundedLoopsStrategy,
@@ -148,6 +149,8 @@ def __init__(
148149
plugin_loader.load(MutationPrunerBuilder())
149150
if not args.disable_iprof:
150151
plugin_loader.load(InstructionProfilerBuilder())
152+
if args.enable_summaries:
153+
plugin_loader.load(SymbolicSummaryPluginBuilder())
151154

152155
plugin_loader.load(CallDepthLimitBuilder())
153156
plugin_loader.add_args(

mythril/interfaces/cli.py

+5
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,11 @@ def add_analysis_args(options):
572572
action="store_true",
573573
help="Disable mutation pruner",
574574
)
575+
options.add_argument(
576+
"--enable-summaries",
577+
action="store_true",
578+
help="Enable using symbolic summaries",
579+
)
575580
options.add_argument(
576581
"--custom-modules-directory",
577582
help="Designates a separate directory to search for custom analysis modules",

mythril/laser/plugin/plugins/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
from mythril.laser.plugin.plugins.mutation_pruner import MutationPrunerBuilder
1212
from mythril.laser.plugin.plugins.call_depth_limiter import CallDepthLimitBuilder
1313
from mythril.laser.plugin.plugins.instruction_profiler import InstructionProfilerBuilder
14+
from mythril.laser.plugin.plugins.summary import SymbolicSummaryPluginBuilder
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .core import SymbolicSummaryPluginBuilder
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from mythril.laser.ethereum.state.annotation import StateAnnotation
2+
from mythril.laser.ethereum.state.global_state import GlobalState
3+
from mythril.laser.ethereum.state.environment import Environment
4+
from mythril.laser.smt import Bool, BaseArray
5+
from typing import List, Tuple
6+
7+
from copy import deepcopy, copy
8+
9+
10+
class SummaryTrackingAnnotation(StateAnnotation):
11+
"""SummaryTrackingAnnotation
12+
This annotation is used by the symbolic summary plugin to keep track of data related to a summary that
13+
will be computed during the future exploration of the annotated world state.
14+
"""
15+
16+
def __init__(
17+
self,
18+
entry: GlobalState,
19+
storage_pairs: List[Tuple[BaseArray, BaseArray]],
20+
storage_constraints: List[Bool],
21+
environment_pair: Tuple[Environment, Environment],
22+
balance_pair: Tuple[BaseArray, BaseArray],
23+
code: str,
24+
):
25+
self.entry = entry
26+
self.trace = []
27+
self.storage_pairs = storage_pairs
28+
self.storage_constraints = storage_constraints
29+
self.environment_pair = environment_pair
30+
self.balance_pair = balance_pair
31+
self.code = code
32+
33+
def __copy__(self):
34+
35+
annotation = SummaryTrackingAnnotation(
36+
entry=self.entry,
37+
storage_pairs=deepcopy(self.storage_pairs),
38+
storage_constraints=deepcopy(self.storage_constraints),
39+
environment_pair=deepcopy(self.environment_pair),
40+
balance_pair=deepcopy(self.balance_pair),
41+
code=self.code,
42+
)
43+
annotation.trace = self.trace
44+
return annotation

0 commit comments

Comments
 (0)