diff --git a/scripts/travis_test_4.sh b/scripts/travis_test_4.sh index 5150a92f6..e940ea86b 100755 --- a/scripts/travis_test_4.sh +++ b/scripts/travis_test_4.sh @@ -102,3 +102,4 @@ test_slither tests/shadowing_builtin_symbols.sol "shadowing-builtin" test_slither tests/shadowing_local_variable.sol "shadowing-local" test_slither tests/solc_version_incorrect.sol "solc-version" test_slither tests/right_to_left_override.sol "rtlo" +test_slither tests/too_many_digits.sol "too-many-digits" diff --git a/slither/detectors/all_detectors.py b/slither/detectors/all_detectors.py index 36c35496c..732bee3b9 100644 --- a/slither/detectors/all_detectors.py +++ b/slither/detectors/all_detectors.py @@ -32,5 +32,6 @@ from .erc20.incorrect_interface import IncorrectERC20InterfaceDetection from .erc20.unindexed_event_parameters import UnindexedERC20EventParameters from .statements.deprecated_calls import DeprecatedStandards from .source.rtlo import RightToLeftOverride +from .statements.too_many_digits import TooManyDigits # # diff --git a/slither/detectors/statements/too_many_digits.py b/slither/detectors/statements/too_many_digits.py new file mode 100644 index 000000000..6049c1371 --- /dev/null +++ b/slither/detectors/statements/too_many_digits.py @@ -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 diff --git a/tests/too_many_digits.sol b/tests/too_many_digits.sol new file mode 100644 index 000000000..409030e3d --- /dev/null +++ b/tests/too_many_digits.sol @@ -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; + } + +}