[Bug-Candidate]: Slither crashes when using the echidna printer in some bytes32 constants
- Dominant language
- Python
- Stars
- 6.4k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the issue:
Slither crashes when trying to print some constant using the echidna printer `--print echidna`
### Code example to reproduce the issue:
```solidity
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IUmbrellaFeeds {
struct PriceData {
uint8 data;
uint24 heartbeat;
uint32 timestamp;
uint128 price;
}
function getPriceData(bytes32 _key) external view returns (PriceData memory data);
}
interface IUmbrellaRegistry {
function getAddress(bytes32 _bytes) external view returns (address);
}
/// @title UmbrellaAggregator
/// @notice Wraps umbrella price feed in an aggregator interface
contract UmbrellaAggregator {
bytes32 public constant FEEDS_KEY_NAME = bytes32("UmbrellaFeeds");
IUmbrellaRegistry public immutable registry;
bytes32 public immutable key;
constructor(bytes32 _key, IUmbrellaRegistry _registry) {
key = _key;
registry = _registry;
}
function latestRoundData() public view returns (uint80, int256 answer, uint256, uint256 updatedAt, uint80) {
_getFeeds().getPriceData(key);
}
function _getFeeds() private view returns (IUmbrellaFeeds) {
return IUmbrellaFeeds(registry.getAddress(FEEDS_KEY_NAME));
}
}
```
### Version:
0.11.3
### Relevant log output:
```shell
Traceback (most recent call last):
File "/opt/homebrew/bin/slither", line 8, in
sys.exit(main())
~~~~^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 776, in main
main_impl(all_detector_classes=detectors, all_printer_classes=printers)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 882, in main_impl
) = process_all(filename, args, detector_classes, printer_classes)
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 107, in process_all
) = process_single(compilation, args, detector_classes, printer_classes)
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 87, in process_single
return _process(slither, detector_classes, printer_classes)
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 143, in _process
printer_results = slither.run_printers()
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/slither.py", line 302, in run_printers
return [p.output(self._crytic_compile.target).data for p in self._printers]
~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/printers/guidance/echidna.py", line 454, in output
(cst_used, cst_used_in_binary) = _extract_constants(contracts)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/printers/guidance/echidna.py", line 285, in _extract_constants
_extract_constants_from_irs(
~~~~~~~~~~~~~~~~~~~~~~~~~~~^
function.all_slithir_operations(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<2 lines>...
context_explored,
^^^^^^^^^^^^^^^^^
)
^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/printers/guidance/echidna.py", line 266, in _extract_constants_from_irs
_extract_constant_from_read(
~~~~~~~~~~~~~~~~~~~~~~~~~~~^
ir, r, all_cst_used, all_cst_used_in_binary, context_explored
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/printers/guidance/echidna.py", line 199, in _extract_constant_from_read
value = ConstantFolding(var_read.expression, value_type).result()
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/visitors/expression/constants_folding.py", line 60, in __init__
super().__init__(expression)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/visitors/expression/expression.py", line 59, in __init__
self._visit_expression(self.expression)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/visitors/expression/expression.py", line 78, in _visit_expression
self._post_visit(expression)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/visitors/expression/expression.py", line 291, in _post_visit
self._post_type_conversion(expression)
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/visitors/expression/constants_folding.py", line 446, in _post_type_conversion
value = convert_string_to_fraction(expr.converted_value)
File "/opt/homebrew/Cellar/slither-analyzer/0.11.3/libexec/lib/python3.13/site-packages/slither/utils/integer_conversion.py", line 20, in convert_string_to_fraction
base, expo = val.split("e") if "e" in val else val.split("E")
^^^^^^^^^^
ValueError: too many values to unpack (expected 2)
```
Contributor guide
Research direction
Reproduce the example with the Echidna printer, then inspect slither/printers/guidance/echidna.py and the traceback paths in slither/visitors/expression/constants_folding.py and slither/utils/integer_conversion.py. Done means the supplied Solidity case no longer crashes when run with --print echidna and the printer completes successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, solidity
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100