Skip to content

Commit

Permalink
Merge pull request #3 from malik672/write_zero
Browse files Browse the repository at this point in the history
Fix bug in gas inefficiency detection for storage writes
  • Loading branch information
malik672 committed Nov 18, 2023
2 parents 0f5e44e + e1f9113 commit 1f92fdd
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 16 deletions.
9 changes: 8 additions & 1 deletion report.json
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
{}
{
"line_17": [
"avoid writing zero to storage slot"
],
"line_21": [
"avoid writing zero to storage slot"
]
}
3 changes: 2 additions & 1 deletion src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ pub async fn loader() {
//Generate the ast
optimizor::ast::ast();

optimizor::write_zero_to_storage::write_zero_to_storage();


//create new JSON Object to store gas inefficiencies
let mut gas_inefficiencies = Map::new();

optimizor::write_zero_to_storage::write_zero_to_storage(&mut gas_inefficiencies, 0);
optimizor::gas_tricks::bytes32(&contract, &mut gas_inefficiencies);
optimizor::gas_tricks::openzepplin(&contract, &mut gas_inefficiencies);
optimizor::gas_tricks::safemath(&contract, &mut gas_inefficiencies);
Expand Down
62 changes: 48 additions & 14 deletions src/optimizor/write_zero_to_storage.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use regex::Regex;
use serde_json::Map;
use serde_json::json;
use serde_json::Value;
use std::fs;

pub fn write_zero_to_storage() {

pub fn write_zero_to_storage(gas_inefficiencies: &mut Map<String, serde_json::Value>, mut _prev: usize) {
let ast_json = fs::read_to_string("src/optimizor/ast.json").expect("Failed to read");
let ast: Value = serde_json::from_str(&ast_json).expect("Failed to deserialize");
let mut _name = "";
let mut _prev: usize = 0;
if let Some(nodes) = ast.get("nodes").and_then(Value::as_array) {
for node in nodes {
if let Some(node_type) = node.get("nodeType").and_then(Value::as_str) {
Expand Down Expand Up @@ -50,10 +52,39 @@ pub fn write_zero_to_storage() {
.as_bool()
.unwrap_or(true)
{
println!(
"Avoid zero to one storage writes where possible. Line: {:?}",
get_line_number_zero(_name, _prev)
_prev = get_line_number_zero(_name, _prev);
let mut inefficiency_id = format!("line_{}", get_line_number_zero(_name, _prev));

get_line_number_zero(_name, _prev);
inefficiency_id = format!("line_{}", _prev);
// Check if the slot exists in the map
if let Some(existing_value) =
gas_inefficiencies
.get_mut(&inefficiency_id)
{
// Slot exists, append the new issue to the existing array
let mut existing_arr: Vec<
String,
> = serde_json::from_value(
existing_value.clone(),
)
.unwrap_or_default();

existing_arr.push("avoid writing zero to storage slot".to_string());

// Update the value in the map
gas_inefficiencies.insert(
inefficiency_id,
json!(existing_arr),
);
} else {
// Slot doesn't exist, create a new entry with a new array
let new_arr = vec!["avoid writing zero to storage slot"];
gas_inefficiencies.insert(
inefficiency_id,
json!(new_arr),
);
}
}
}
}
Expand All @@ -71,25 +102,28 @@ pub fn write_zero_to_storage() {
}
}

fn get_line_number_zero(src: &str, mut _prev: usize) -> String {
fn get_line_number_zero(src: &str, mut _prev: usize) -> usize {
// Read the source file as a string
let contract = fs::read_to_string("src/contract.sol").expect("Failed to read");

// Split the contract content into lines
let lines: Vec<&str> = contract.lines().collect();

// Format the string with " = 0" at the end
let strss = format!("{} = 0", src);
let strss = format!(r"{} = 0", src);

// Compile the regex pattern
let variable_declaration_regex = Regex::new(&strss).unwrap();

let mut _line_numbers = 0;
for (mut line_number, line) in lines.iter().enumerate() {
line_number = _prev;
_line_numbers = line_number + 1;
if let Some(_capture) = variable_declaration_regex.captures(line) {}
_prev = _line_numbers;

for (line_number, line) in lines.iter().enumerate() {
if let Some(_capture) = variable_declaration_regex.captures(line) {
if line_number > _prev {
_prev = line_number + 1;
break;
}

}
}
_prev.to_string()
_prev
}

0 comments on commit 1f92fdd

Please sign in to comment.