solstat/analyzer/optimizations/
sstore.rs1use std::collections::HashSet;
2
3use solang_parser::pt::{self, Loc};
4use solang_parser::{self, pt::SourceUnit};
5
6use crate::analyzer::ast::{self, Target};
7use crate::analyzer::utils;
8
9pub fn sstore_optimization(source_unit: SourceUnit) -> HashSet<Loc> {
10 let mut optimization_locations: HashSet<Loc> = HashSet::new();
12
13 let storage_variables = utils::get_32_byte_storage_variables(source_unit.clone(), true, true);
15
16 let target_nodes = ast::extract_target_from_node(Target::Assign, source_unit.into());
18
19 for node in target_nodes {
20 let expression = node.expression().unwrap();
22
23 if let pt::Expression::Assign(loc, box_expression, _) = expression {
25 if let pt::Expression::Variable(identifier) = *box_expression {
27 if storage_variables.contains_key(&identifier.name) {
29 optimization_locations.insert(loc);
31 }
32 }
33 }
34 }
35 optimization_locations
37}
38#[test]
39fn test_sstore_optimization() {
40 let file_contents = r#"
41
42 pragma solidity >= 0.8.0;
43 contract Contract {
44
45 uint256 thing = 100;
46 address someAddress = address(0);
47 bytes someBytes;
48
49
50
51 function testFunction() public {
52 thing = 1+2;
53 someAddress = msg.sender;
54 someBytes = bytes(0);
55
56
57 }
58 }
59
60 "#;
61 let source_unit = solang_parser::parse(file_contents, 0).unwrap().0;
62
63 let optimization_locations = sstore_optimization(source_unit);
64
65 assert_eq!(optimization_locations.len(), 3);
66}