Skip to content

Commit

Permalink
add more gas-tricks
Browse files Browse the repository at this point in the history
  • Loading branch information
malik672 committed Nov 2, 2023
1 parent 08c4cf2 commit c6c804a
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ ethers-solc = "2.0.10"
regex = "1.10.2"
reqwest = "0.11.22"
serde_json = "1.0.107"
snap = "1.1.0"
tokio = {version = "1", features = ["full"]}
1 change: 0 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
pub fn cli() {}
7 changes: 7 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use reqwest::Error;
use serde_json::{Map, Value};
use tokio;
use std::fs;
mod config;

fn read_sol_file(file_path: &str) -> Result<String, std::io::Error> {
// Read the contents of the Solidity file into a string
Expand Down Expand Up @@ -30,6 +31,7 @@ mod optimizor {
#[tokio::main]
async fn main() {
let contract: &str = &read_sol_file("./src/contract.sol").unwrap();
config::cli();

//create new JSON Object to store gas inefficiencies
let mut gas_inefficiencies = Map::new();
Expand All @@ -44,6 +46,11 @@ async fn main() {
optimizor::gas_tricks::uint_incur_overhead(contract, &mut gas_inefficiencies);
optimizor::gas_tricks::mapping_instead_array(contract, &mut gas_inefficiencies);
optimizor::gas_tricks::uint256_instead_bool(contract, &mut gas_inefficiencies);
optimizor::gas_tricks::require_double_logic(contract, &mut gas_inefficiencies);
optimizor::gas_tricks::revert_32(contract, &mut gas_inefficiencies);
optimizor::gas_tricks::do_while(contract, &mut gas_inefficiencies);
optimizor::gas_tricks::priv_constants_immut(contract, &mut gas_inefficiencies);
optimizor::gas_tricks::emit_loops(contract, &mut gas_inefficiencies);

// Convert the gas inefficiencies to JSON
let gas_inefficiencies_json =
Expand Down
84 changes: 84 additions & 0 deletions src/optimizor/gas_tricks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,87 @@ pub fn use_named_retunrs(contract: &str, gas_inefficiencies: &mut Map<String, se
}
}
}

pub fn require_double_logic(
contract: &str,
gas_inefficiencies: &mut Map<String, serde_json::Value>,
) {
let regexe = Regex::new(r"require\(.*&&.*\);").unwrap();
let lines: Vec<&str> = contract.lines().collect();
for (line_number, line) in lines.iter().enumerate() {
if regexe.captures(line).is_some() {
let inefficiency_id = format!("line_{}", line_number + 1);
println!("split require statements ");

gas_inefficiencies.insert(
inefficiency_id,
"split require statements that use && into two seperate parts to save gas ".into(),
);
}
}
}

pub fn revert_32(contract: &str, gas_inefficiencies: &mut Map<String, serde_json::Value>) {
let regexe = Regex::new(r"revert\(.*\'.{33,}\'.*\);").unwrap();
let lines: Vec<&str> = contract.lines().collect();
for (line_number, line) in lines.iter().enumerate() {
if regexe.captures(line).is_some() {
let inefficiency_id = format!("line_{}", line_number + 1);
println!("string length more thaan 32 ");

gas_inefficiencies.insert(
inefficiency_id,
"revert statement that has it's string longer than 32 length is always more expensive ".into(),
);
}
}
}

pub fn do_while(contract: &str, gas_inefficiencies: &mut Map<String, serde_json::Value>) {
let regexe = Regex::new(r"\bfor\s*\(").unwrap();
let lines: Vec<&str> = contract.lines().collect();
for (line_number, line) in lines.iter().enumerate() {
if regexe.captures(line).is_some() {
let inefficiency_id = format!("line_{}", line_number + 1);
println!("use do while loops instead of for loops ");

gas_inefficiencies.insert(
inefficiency_id,
"do while loops are cheaper than loops and consume less gas ".into(),
);
}
}
}

pub fn priv_constants_immut(contract: &str, gas_inefficiencies: &mut Map<String, serde_json::Value>) {
let regexe = Regex::new(r"\bpublic\b.*(constant | immutable)").unwrap();
let lines: Vec<&str> = contract.lines().collect();
for (line_number, line) in lines.iter().enumerate() {
if regexe.captures(line).is_some() {
let inefficiency_id = format!("line_{}", line_number + 1);
println!("variables that are constant should have a visibility of private");

gas_inefficiencies.insert(
inefficiency_id,
"variables that are constant should have a visibility of private".into(),
);
}
}
}


pub fn emit_loops(contract: &str, gas_inefficiencies: &mut Map<String, serde_json::Value>) {
let regexe = Regex::new(r"\bfor\s*\(\s*.*emit").unwrap();
let lines: Vec<&str> = contract.lines().collect();
for (line_number, line) in lines.iter().enumerate() {
if regexe.captures(line).is_some() {
let inefficiency_id = format!("line_{}", line_number + 1);
println!("emiting events in loops cost more, and should be done using other means");

gas_inefficiencies.insert(
inefficiency_id,
"emiting events in loops cost more, and should be done using other means".into(),
);
}
}
}

0 comments on commit c6c804a

Please sign in to comment.