solstat/analyzer/optimizations/
sstore.rs

1use 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    //Create a new hashset that stores the location of each optimization target identified
11    let mut optimization_locations: HashSet<Loc> = HashSet::new();
12
13    //Get all storage variables
14    let storage_variables = utils::get_32_byte_storage_variables(source_unit.clone(), true, true);
15
16    //Extract the target nodes from the source_unit
17    let target_nodes = ast::extract_target_from_node(Target::Assign, source_unit.into());
18
19    for node in target_nodes {
20        //We can use unwrap because Target::Assign is an expression
21        let expression = node.expression().unwrap();
22
23        //if the expression is an Assign
24        if let pt::Expression::Assign(loc, box_expression, _) = expression {
25            //if the first expr in the assign expr is a variable
26            if let pt::Expression::Variable(identifier) = *box_expression {
27                //if the variable name exists in the storage variable hashmap
28                if storage_variables.contains_key(&identifier.name) {
29                    //add the location to the optimization locations
30                    optimization_locations.insert(loc);
31                }
32            }
33        }
34    }
35    //Return the identified optimization locations
36    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}