Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
montyly committed Dec 7, 2020
2 parents 37a44b3 + f9f4005 commit 84947b0
Show file tree
Hide file tree
Showing 128 changed files with 1,114 additions and 64 deletions.
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
install_requires=[
"prettytable>=0.7.2",
"pysha3>=1.0.2",
# "crytic-compile>=0.1.10",
"crytic-compile",
"crytic-compile>=0.1.11",
# "crytic-compile",
],
dependency_links=["git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile"],
# dependency_links=["git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile"],
license="AGPL-3.0",
long_description=open("README.md").read(),
entry_points={
Expand Down
23 changes: 11 additions & 12 deletions slither/detectors/statements/boolean_constant_equality.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class BooleanEquality(AbstractDetector):
"""
Boolean constant misuse
Boolean constant equality
"""

ARGUMENT = "boolean-equal"
Expand Down Expand Up @@ -72,17 +72,16 @@ def _detect(self):
results = []
for contract in self.contracts:
boolean_constant_misuses = self._detect_boolean_equality(contract)
if boolean_constant_misuses:
for (func, nodes) in boolean_constant_misuses:
for node in nodes:
info = [
func,
" compares to a boolean constant:\n\t-",
node,
"\n",
]
for (func, nodes) in boolean_constant_misuses:
for node in nodes:
info = [
func,
" compares to a boolean constant:\n\t-",
node,
"\n",
]

res = self.generate_result(info)
results.append(res)
res = self.generate_result(info)
results.append(res)

return results
61 changes: 28 additions & 33 deletions slither/detectors/statements/boolean_constant_misuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,39 +67,35 @@ def _detect_boolean_constant_misuses(contract): # pylint: disable=too-many-bran
results = []

# Loop for each function and modifier.
for function in contract.functions_declared: # pylint: disable=too-many-nested-blocks
for function in contract.functions_declared:
f_results = set()

# Loop for every node in this function, looking for boolean constants
for node in function.nodes:

# Do not report "while(true)"
if node.type == NodeType.IFLOOP:
if node.irs:
if len(node.irs) == 1:
ir = node.irs[0]
if isinstance(ir, Condition) and ir.value == Constant(
"True", ElementaryType("bool")
):
continue
if node.type == NodeType.IFLOOP and node.irs and len(node.irs) == 1:
ir = node.irs[0]
if isinstance(ir, Condition) and ir.value == Constant(
"True", ElementaryType("bool")
):
continue

for ir in node.irs:
if isinstance(ir, (Assignment, Call, Return, InitArray)):
# It's ok to use a bare boolean constant in these contexts
continue
if isinstance(ir, Binary):
if ir.type in [
BinaryType.ADDITION,
BinaryType.EQUAL,
BinaryType.NOT_EQUAL,
]:
# Comparing to a Boolean constant is dubious style, but harmless
# Equal is catch by another detector (informational severity)
continue
if isinstance(ir, Binary) and ir.type in [
BinaryType.ADDITION,
BinaryType.EQUAL,
BinaryType.NOT_EQUAL,
]:
# Comparing to a Boolean constant is dubious style, but harmless
# Equal is catch by another detector (informational severity)
continue
for r in ir.read:
if isinstance(r, Constant):
if isinstance(r.value, bool):
f_results.add(node)
if isinstance(r, Constant) and isinstance(r.value, bool):
f_results.add(node)
results.append((function, f_results))

# Return the resulting set of nodes with improper uses of Boolean constants
Expand All @@ -112,17 +108,16 @@ def _detect(self):
results = []
for contract in self.contracts:
boolean_constant_misuses = self._detect_boolean_constant_misuses(contract)
if boolean_constant_misuses:
for (func, nodes) in boolean_constant_misuses:
for node in nodes:
info = [
func,
" uses a Boolean constant improperly:\n\t-",
node,
"\n",
]

res = self.generate_result(info)
results.append(res)
for (func, nodes) in boolean_constant_misuses:
for node in nodes:
info = [
func,
" uses a Boolean constant improperly:\n\t-",
node,
"\n",
]

res = self.generate_result(info)
results.append(res)

return results
16 changes: 9 additions & 7 deletions slither/solc_parsing/declarations/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ def __init__(self, event: Event, event_data: Dict, contract_parser: "ContractSol
self._elemsNotParsed = elems["parameters"]
else:
self._event.name = event_data["attributes"]["name"]
elems = event_data["children"][0]

assert elems["name"] == "ParameterList"
if "children" in elems:
self._elemsNotParsed = elems["children"]
else:
self._elemsNotParsed = []
for elem in event_data["children"]:
# From Solidity 0.6.3 to 0.6.10 (included)
# Comment above a event might be added in the children
# of an event for the legacy ast
if elem["name"] == "ParameterList":
if "children" in elem:
self._elemsNotParsed = elem["children"]
else:
self._elemsNotParsed = []

@property
def is_compact_ast(self) -> bool:
Expand Down
12 changes: 10 additions & 2 deletions slither/solc_parsing/declarations/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,16 @@ def analyze_params(self):
returns = self._functionNotParsed["returnParameters"]
else:
children = self._functionNotParsed[self.get_children("children")]
params = children[0]
returns = children[1]
# It uses to be
# params = children[0]
# returns = children[1]
# But from Solidity 0.6.3 to 0.6.10 (included)
# Comment above a function might be added in the children
child_iter = iter(
[child for child in children if child[self.get_key()] == "ParameterList"]
)
params = next(child_iter)
returns = next(child_iter)

if params:
self._parse_params(params)
Expand Down
14 changes: 10 additions & 4 deletions slither/solc_parsing/declarations/modifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ def analyze_params(self):
params = self._functionNotParsed["parameters"]
else:
children = self._functionNotParsed["children"]
params = children[0]
# It uses to be
# params = children[0]
# But from Solidity 0.6.3 to 0.6.10 (included)
# Comment above a function might be added in the children
params = next(child for child in children if child[self.get_key()] == "ParameterList")

if params:
self._parse_params(params)
Expand All @@ -60,9 +64,11 @@ def analyze_content(self):

self._function.is_implemented = False
if len(children) > 1:
assert len(children) == 2
block = children[1]
assert block["name"] == "Block"
# It uses to be
# params = children[1]
# But from Solidity 0.6.3 to 0.6.10 (included)
# Comment above a function might be added in the children
block = next(child for child in children if child[self.get_key()] == "Block")
self._function.is_implemented = True
self._parse_cfg(block)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
name="crytic_supply_constant_ERC20PropertiesNotMintable()",
description="The total supply does not increase.",
content="""
\t\treturn initialTotalSupply >= totalSupply();""",
\t\treturn initialTotalSupply >= this.totalSupply();""",
type=PropertyType.MEDIUM_SEVERITY,
return_type=PropertyReturn.SUCCESS,
is_unit_test=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
name="crytic_less_than_total_ERC20Properties()",
description="Balance of one user must be less or equal to the total supply.",
content="""
\t\treturn this.balanceOf(msg.sender) <= totalSupply();""",
\t\treturn this.balanceOf(msg.sender) <= this.totalSupply();""",
type=PropertyType.MEDIUM_SEVERITY,
return_type=PropertyReturn.SUCCESS,
is_unit_test=True,
Expand All @@ -48,7 +48,7 @@
name="crytic_totalSupply_consistant_ERC20Properties()",
description="Balance of the crytic users must be less or equal to the total supply.",
content="""
\t\treturn this.balanceOf(crytic_owner) + this.balanceOf(crytic_user) + this.balanceOf(crytic_attacker) <= totalSupply();""",
\t\treturn this.balanceOf(crytic_owner) + this.balanceOf(crytic_user) + this.balanceOf(crytic_attacker) <= this.totalSupply();""",
type=PropertyType.MEDIUM_SEVERITY,
return_type=PropertyReturn.SUCCESS,
is_unit_test=True,
Expand Down
7 changes: 7 additions & 0 deletions tests/ast-parsing/comment-all.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
contract A{
/*** Events ***/
event E();

/*** Function ***/
function f() public{}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.0-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.1-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.10-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.11-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.12-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.12-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.13-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.13-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.14-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.14-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.15-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.15-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.16-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.16-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.17-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.17-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.18-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.18-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.19-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.19-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.2-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
5 changes: 5 additions & 0 deletions tests/ast-parsing/expected/comment-0.4.20-compact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"A": {
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n"
}
}
Loading

0 comments on commit 84947b0

Please sign in to comment.