mirror of https://github.com/crytic/slither
Merge branch 'dev-too-many-digits' of https://github.com/GillesdeB/slither into GillesdeB-dev-too-many-digits
commit
152f62e57d
@ -0,0 +1,54 @@ |
|||||||
|
""" |
||||||
|
Module detecting numbers with too many digits. |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
class TooManyDigits(AbstractDetector): |
||||||
|
""" |
||||||
|
Detect numbers with too many digits |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = 'too_many_digits' # slither will launch the detector with slither.py --too_many_digits |
||||||
|
HELP = 'Numbers with too many digits (human readability risk)' |
||||||
|
IMPACT = DetectorClassification.MEDIUM |
||||||
|
CONFIDENCE = DetectorClassification.MEDIUM |
||||||
|
|
||||||
|
WIKI = 'https://github.com/ethereum/web3.js/blob/0.15.0/lib/utils/utils.js' |
||||||
|
WIKI_TITLE = 'too_many_digits' |
||||||
|
WIKI_DESCRIPTION = 'Plugin too_many_digits' |
||||||
|
WIKI_EXPLOIT_SCENARIO = 'An error or malicious intent may have caused a number with many digits to be different than the number originally intended. This kind of error is usually difficult to find visually.' |
||||||
|
WIKI_RECOMMENDATION = 'The number used in the contract has too many digits. Try to use an Ether denomination instead' |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
results = [] |
||||||
|
|
||||||
|
from slither import Slither |
||||||
|
from slither.slithir.variables import Constant |
||||||
|
|
||||||
|
# iterate over all contracts |
||||||
|
for contract in self.slither.contracts_derived: |
||||||
|
# iterate over all functions |
||||||
|
for f in contract.functions: |
||||||
|
# iterate over all the nodes |
||||||
|
for node in f.nodes: |
||||||
|
# each node contains a list of IR instruction |
||||||
|
for ir in node.irs: |
||||||
|
# iterate over all the variables read by the IR |
||||||
|
for read in ir.read: |
||||||
|
# if the variable is a constant |
||||||
|
if isinstance(read, Constant): |
||||||
|
# read.value can return an int or a str. Convert it to str |
||||||
|
value_as_str = str(read.value) |
||||||
|
#name_as_str = str(read.name) |
||||||
|
line_of_code = str(node.expression) |
||||||
|
if '00000' in value_as_str: |
||||||
|
# Info to be printed |
||||||
|
info = 'In {}.{} ({}), too many digits used in expression:\n\t- {}\n\tPlease use the proper Ether denomination instead\n' |
||||||
|
info = info.format(contract.name, f.name, f.source_mapping_str, line_of_code) |
||||||
|
|
||||||
|
# Add the result in result |
||||||
|
json = self.generate_json_result(info) |
||||||
|
self.add_function_to_json(f, json) |
||||||
|
results.append(json) |
||||||
|
return results |
@ -0,0 +1,35 @@ |
|||||||
|
pragma solidity ^0.5.7; |
||||||
|
|
||||||
|
contract C { |
||||||
|
uint balance; |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Variables are not Ok - using too many digits in place of the Ether denomination. |
||||||
|
*/ |
||||||
|
function f() external { |
||||||
|
uint x1 = 0x000001; |
||||||
|
uint x2 = 0x0000000000001; |
||||||
|
uint x3 = 1000000000000000000; |
||||||
|
uint x4 = 100000; |
||||||
|
balance += x1 + x2 + x3 + x4; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Variables are Ok - not using too many digits. |
||||||
|
*/ |
||||||
|
function h() external { |
||||||
|
uint x1 = 1000; |
||||||
|
uint x2 = 100000; |
||||||
|
balance += x1 + x2 + 100; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Variables are Ok - Using Ether denominations. |
||||||
|
*/ |
||||||
|
function i() external { |
||||||
|
uint x1 = 1 wei + 10 wei + 100 wei + 1000 wei + 10000 wei; |
||||||
|
uint x2 = 1 szabo + 10 szabo + 100 szabo + 1000 szabo + 10000 szabo; |
||||||
|
balance += x1 + x2; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue