From d592e76dea61bea5c65c77b1fef968e023ddf109 Mon Sep 17 00:00:00 2001 From: Simone Date: Tue, 20 Feb 2024 19:46:09 +0100 Subject: [PATCH 1/2] Track storage variables read/written in assembly --- slither/core/cfg/node.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/slither/core/cfg/node.py b/slither/core/cfg/node.py index 9b53b0db92..87d0e16a2e 100644 --- a/slither/core/cfg/node.py +++ b/slither/core/cfg/node.py @@ -11,6 +11,7 @@ SolidityFunction, ) from slither.core.expressions.expression import Expression +from slither.core.expressions import CallExpression, Identifier, AssignmentOperation from slither.core.solidity_types import ElementaryType from slither.core.source_mapping.source_mapping import SourceMapping from slither.core.variables.local_variable import LocalVariable @@ -898,6 +899,21 @@ def _find_read_write_call(self) -> None: # pylint: disable=too-many-statements # TODO: consider removing dependancy of solidity_call to internal_call self._solidity_calls.append(ir.function) self._internal_calls.append(ir.function) + if ( + isinstance(ir, SolidityCall) + and ir.function == SolidityFunction("sstore(uint256,uint256)") + and isinstance(ir.node.expression, CallExpression) + and isinstance(ir.node.expression.arguments[0], Identifier) + ): + self._vars_written.append(ir.arguments[0]) + if ( + isinstance(ir, SolidityCall) + and ir.function == SolidityFunction("sload(uint256)") + and isinstance(ir.node.expression, AssignmentOperation) + and isinstance(ir.node.expression.expression_right, CallExpression) + and isinstance(ir.node.expression.expression_right.arguments[0], Identifier) + ): + self._vars_read.append(ir.arguments[0]) if isinstance(ir, LowLevelCall): assert isinstance(ir.destination, (Variable, SolidityVariable)) self._low_level_calls.append((ir.destination, str(ir.function_name.value))) From 801a13e6004b3fdd66ea6689d823e5581dff29e7 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 29 Feb 2024 11:13:26 -0600 Subject: [PATCH 2/2] add regression test for https://github.com/crytic/slither/issues/2325 --- .../0.8.0/const_state_variables.sol | 9 +++++++-- .../0.8.0/const_state_variables.sol-0.8.0.zip | Bin 8365 -> 8993 bytes 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/e2e/detectors/test_data/constable-states/0.8.0/const_state_variables.sol b/tests/e2e/detectors/test_data/constable-states/0.8.0/const_state_variables.sol index f405a15875..00b0955c85 100644 --- a/tests/e2e/detectors/test_data/constable-states/0.8.0/const_state_variables.sol +++ b/tests/e2e/detectors/test_data/constable-states/0.8.0/const_state_variables.sol @@ -66,7 +66,7 @@ contract Good { uint immutable should_be_immutable_3 = 10 + block.number; B immutable should_be_immutable_4 = new B(); uint immutable should_be_immutable_5; - + uint blobBaseFee; constructor(uint b) { should_be_immutable_5 = b; } @@ -74,5 +74,10 @@ contract Good { function getNumber() public returns(uint){ return block.number; } - + + function updateBlobBaseFee(uint _blobBaseFee) public { + assembly { + sstore(blobBaseFee.slot, _blobBaseFee) + } + } } \ No newline at end of file diff --git a/tests/e2e/detectors/test_data/constable-states/0.8.0/const_state_variables.sol-0.8.0.zip b/tests/e2e/detectors/test_data/constable-states/0.8.0/const_state_variables.sol-0.8.0.zip index d04c3f8e79c1a87787c6abc5a9ca6fb901b42ddb..7afd3884bb35261471e4fb871c6da2a5f91b454f 100644 GIT binary patch delta 8759 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