diff --git a/artifacts/contract.sol/Counter1.json b/artifacts/contract.sol/Counter1.json index 7f3421a..dea7a98 100644 --- a/artifacts/contract.sol/Counter1.json +++ b/artifacts/contract.sol/Counter1.json @@ -1,50 +1,26 @@ { - "abi": [ - { - "inputs": [], - "name": "increment", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "number", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } - ], + "abi": [], "bytecode": { - "object": "0x608060405234801561001057600080fd5b5060e38061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80638381f58a146037578063d09de08a146051575b600080fd5b603d6059565b604051604891906094565b60405180910390f35b6057605f565b005b60005481565b600054600a11606d57600080fd5b600054601411607b57600080fd5b565b6000819050919050565b608e81607d565b82525050565b600060208201905060a760008301846087565b9291505056fea26469706673582212208fda61b21f32332065be61c9b6c9d133e91372becc160b991b3c640ba2a966a464736f6c634300080c0033", - "sourceMap": "57:203:0:-:0;;;;;;;;;;;;;;;;;;;", + "object": "0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea26469706673582212207d5b2e024befc9ab05740da99af14e58cd223eb400daf9e08f6fd35c433a2da564736f6c634300080c0033", + "sourceMap": "57:132:0:-:0;;;;;;;;;;;;;;;;;;;", "linkReferences": {} }, "deployedBytecode": { - "object": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80638381f58a146037578063d09de08a146051575b600080fd5b603d6059565b604051604891906094565b60405180910390f35b6057605f565b005b60005481565b600054600a11606d57600080fd5b600054601411607b57600080fd5b565b6000819050919050565b608e81607d565b82525050565b600060208201905060a760008301846087565b9291505056fea26469706673582212208fda61b21f32332065be61c9b6c9d133e91372becc160b991b3c640ba2a966a464736f6c634300080c0033", - "sourceMap": "57:203:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;163:95;;;:::i;:::-;;81:21;;;;:::o;163:95::-;214:6;;209:2;:11;201:20;;;;;;244:6;;239:2;:11;231:20;;;;;;163:95::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o", + "object": "0x6080604052600080fdfea26469706673582212207d5b2e024befc9ab05740da99af14e58cd223eb400daf9e08f6fd35c433a2da564736f6c634300080c0033", + "sourceMap": "57:132:0:-:0;;;;;", "linkReferences": {} }, - "methodIdentifiers": { - "increment()": "d09de08a", - "number()": "8381f58a" - }, + "methodIdentifiers": {}, "ast": { "absolutePath": "src/contract.sol", - "id": 25, + "id": 12, "exportedSymbols": { "Counter1": [ - 24 + 11 ] }, "nodeType": "SourceUnit", - "src": "32:230:0", + "src": "32:159:0", "nodes": [ { "id": 1, @@ -58,309 +34,129 @@ ] }, { - "id": 24, + "id": 11, "nodeType": "ContractDefinition", - "src": "57:203:0", + "src": "57:132:0", "nodes": [ { - "id": 3, - "nodeType": "VariableDeclaration", - "src": "81:21:0", - "nodes": [], - "constant": false, - "functionSelector": "8381f58a", - "mutability": "mutable", - "name": "number", - "nameLocation": "96:6:0", - "scope": 24, - "stateVariable": true, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "81:7:0", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "public" - }, - { - "id": 5, - "nodeType": "VariableDeclaration", - "src": "108:21:0", - "nodes": [], - "constant": false, - "mutability": "mutable", - "name": "ionize", - "nameLocation": "123:6:0", - "scope": 24, - "stateVariable": true, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_string_storage", - "typeString": "string" - }, - "typeName": { - "id": 4, - "name": "string", - "nodeType": "ElementaryTypeName", - "src": "108:6:0", - "typeDescriptions": { - "typeIdentifier": "t_string_storage_ptr", - "typeString": "string" - } - }, - "visibility": "private" - }, - { - "id": 7, - "nodeType": "VariableDeclaration", - "src": "135:21:0", - "nodes": [], - "constant": false, - "mutability": "mutable", - "name": "localize", - "nameLocation": "148:8:0", - "scope": 24, - "stateVariable": true, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - }, - "typeName": { - "id": 6, - "name": "bool", - "nodeType": "ElementaryTypeName", - "src": "135:4:0", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "visibility": "private" - }, - { - "id": 23, - "nodeType": "FunctionDefinition", - "src": "163:95:0", + "id": 10, + "nodeType": "StructDefinition", + "src": "84:102:0", "nodes": [], - "body": { - "id": 22, - "nodeType": "Block", - "src": "191:67:0", - "nodes": [], - "statements": [ - { - "expression": { - "arguments": [ - { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 13, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "hexValue": "3130", - "id": 11, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "209:2:0", - "typeDescriptions": { - "typeIdentifier": "t_rational_10_by_1", - "typeString": "int_const 10" - }, - "value": "10" - }, - "nodeType": "BinaryOperation", - "operator": ">", - "rightExpression": { - "id": 12, - "name": "number", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 3, - "src": "214:6:0", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "209:11:0", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - ], - "id": 10, - "name": "require", - "nodeType": "Identifier", - "overloadedDeclarations": [ - -18, - -18 - ], - "referencedDeclaration": -18, - "src": "201:7:0", - "typeDescriptions": { - "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", - "typeString": "function (bool) pure" - } - }, - "id": 14, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "201:20:0", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 15, - "nodeType": "ExpressionStatement", - "src": "201:20:0" + "canonicalName": "Counter1.red", + "members": [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "errrr", + "nameLocation": "110:5:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "105:10:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "105:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 5, + "mutability": "mutable", + "name": "unite", + "nameLocation": "132:5:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "125:12:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + }, + "typeName": { + "id": 4, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "125:6:0", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } }, - { - "expression": { - "arguments": [ - { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 19, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "hexValue": "3230", - "id": 17, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "239:2:0", - "typeDescriptions": { - "typeIdentifier": "t_rational_20_by_1", - "typeString": "int_const 20" - }, - "value": "20" - }, - "nodeType": "BinaryOperation", - "operator": ">", - "rightExpression": { - "id": 18, - "name": "number", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 3, - "src": "244:6:0", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "239:11:0", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - ], - "id": 16, - "name": "require", - "nodeType": "Identifier", - "overloadedDeclarations": [ - -18, - -18 - ], - "referencedDeclaration": -18, - "src": "231:7:0", - "typeDescriptions": { - "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", - "typeString": "function (bool) pure" - } - }, - "id": 20, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "231:20:0", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 21, - "nodeType": "ExpressionStatement", - "src": "231:20:0" - } - ] - }, - "functionSelector": "d09de08a", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "increment", - "nameLocation": "172:9:0", - "parameters": { - "id": 8, - "nodeType": "ParameterList", - "parameters": [], - "src": "181:2:0" - }, - "returnParameters": { - "id": 9, - "nodeType": "ParameterList", - "parameters": [], - "src": "191:0:0" - }, - "scope": 24, - "stateMutability": "nonpayable", - "virtual": false, + "visibility": "internal" + }, + { + "constant": false, + "id": 7, + "mutability": "mutable", + "name": "ras3", + "nameLocation": "153:4:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "147:10:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 6, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "147:5:0", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 9, + "mutability": "mutable", + "name": "dear", + "nameLocation": "175:4:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "167:12:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes20", + "typeString": "bytes20" + }, + "typeName": { + "id": 8, + "name": "bytes20", + "nodeType": "ElementaryTypeName", + "src": "167:7:0", + "typeDescriptions": { + "typeIdentifier": "t_bytes20", + "typeString": "bytes20" + } + }, + "visibility": "internal" + } + ], + "name": "red", + "nameLocation": "91:3:0", + "scope": 11, "visibility": "public" } ], @@ -371,11 +167,11 @@ "contractKind": "contract", "fullyImplemented": true, "linearizedBaseContracts": [ - 24 + 11 ], "name": "Counter1", "nameLocation": "66:8:0", - "scope": 25, + "scope": 12, "usedErrors": [] } ], diff --git a/cache/solidity-files-cache.json b/cache/solidity-files-cache.json index 446e1dd..377d986 100644 --- a/cache/solidity-files-cache.json +++ b/cache/solidity-files-cache.json @@ -12,8 +12,8 @@ }, "files": { "src/contract.sol": { - "lastModificationDate": 1700762187306, - "contentHash": "4cfab11a6c48fe1603a2ee6922e55b0a", + "lastModificationDate": 1700945211440, + "contentHash": "1a8e4caa9ef81d181c8999b58c93d77f", "sourceName": "src/contract.sol", "solcConfig": { "settings": { diff --git a/report.json b/report.json index 9e26dfe..d93465c 100644 --- a/report.json +++ b/report.json @@ -1 +1,5 @@ -{} \ No newline at end of file +{ + "line_7": [ + "struct is arraged wrongly should be arranged in this way [\"uint8\", \"bytes20\", \"uint\", \"string\"]" + ] +} \ No newline at end of file diff --git a/src/contract.sol b/src/contract.sol index 4641e7f..fca4d71 100644 --- a/src/contract.sol +++ b/src/contract.sol @@ -2,13 +2,14 @@ pragma solidity 0.8.12; contract Counter1 { - uint256 public number; - string private ionize; - bool private localize; + - function increment() public { - require(10 > number); - require(20 > number); + struct red { + uint errrr; + string unite; + uint8 ras3; + bytes20 dear; } + } diff --git a/src/loader.rs b/src/loader.rs index c8e9693..aacf70a 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -1,8 +1,6 @@ -use reqwest; -use reqwest::Error; +use crate::optimizor; use serde_json::{Map, Value}; use std::fs; -use crate::optimizor; fn read_sol_file(file_path: &str) -> Result { // Read the contents of the Solidity file into a string @@ -11,41 +9,28 @@ fn read_sol_file(file_path: &str) -> Result { Ok(content) } -// async fn read_from_github(path: &str) -> Result { -// // Send an HTTP GET request to fetch the raw content -// //Path should be in this format: https://raw.githubusercontent.com/user/repo/master/contract.sol -// let client = reqwest::Client::new(); -// let response = client.get(path).send().await?; -// let contract_content = response.text().await?; -// println!("{}", contract_content); - -// Ok(contract_content) - -// } - pub async fn loader() { - // // Parse command-line arguments using the config module // let (input_file, github_url) = config::parse_args(); // // Initialize the contract variable // let contract: String; - + // if let Some(url) = github_url { // // Read from a GitHub URL // contract = read_from_github(&url).await.unwrap(); // } else { // // Read from a local file - let contract = read_sol_file("src/contract.sol").unwrap(); + let contract = read_sol_file("src/contract.sol").unwrap(); // } //Generate the ast optimizor::ast::ast(); - //create new JSON Object to store gas + //create new JSON Object to store gas let mut gas_inefficiencies = Map::new(); - + optimizor::struct_packing::struct_packing(&mut gas_inefficiencies, 0); optimizor::cache_state_variables::cache_state_variables(&mut gas_inefficiencies, 0); optimizor::write_zero_to_storage::write_zero_to_storage(&mut gas_inefficiencies, 0); optimizor::bytes32::bytes32(&contract, &mut gas_inefficiencies); @@ -70,5 +55,4 @@ pub async fn loader() { // Save the JSON to a file let json_file_path = "report.json"; fs::write(json_file_path, gas_inefficiencies_json).expect("Unable to write JSON file"); - } diff --git a/src/main.rs b/src/main.rs index 303e8c9..3791c8d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,8 @@ -use tokio; mod config; mod loader; mod optimizor; mod utils; - #[tokio::main] async fn main() { loader::loader().await; diff --git a/src/optimizor/ast.json b/src/optimizor/ast.json index a0e8e64..b41556e 100644 --- a/src/optimizor/ast.json +++ b/src/optimizor/ast.json @@ -1 +1 @@ -{"absolutePath":"src/contract.sol","id":25,"exportedSymbols":{"Counter1":[24]},"nodeType":"SourceUnit","src":"32:230:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".12"]},{"id":24,"nodeType":"ContractDefinition","src":"57:203:0","nodes":[{"id":3,"nodeType":"VariableDeclaration","src":"81:21:0","nodes":[],"constant":false,"functionSelector":"8381f58a","mutability":"mutable","name":"number","nameLocation":"96:6:0","scope":24,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2,"name":"uint256","nodeType":"ElementaryTypeName","src":"81:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":5,"nodeType":"VariableDeclaration","src":"108:21:0","nodes":[],"constant":false,"mutability":"mutable","name":"ionize","nameLocation":"123:6:0","scope":24,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string"},"typeName":{"id":4,"name":"string","nodeType":"ElementaryTypeName","src":"108:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"private"},{"id":7,"nodeType":"VariableDeclaration","src":"135:21:0","nodes":[],"constant":false,"mutability":"mutable","name":"localize","nameLocation":"148:8:0","scope":24,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":6,"name":"bool","nodeType":"ElementaryTypeName","src":"135:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"private"},{"id":23,"nodeType":"FunctionDefinition","src":"163:95:0","nodes":[],"body":{"id":22,"nodeType":"Block","src":"191:67:0","nodes":[],"statements":[{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":13,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":11,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"209:2:0","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":">","rightExpression":{"id":12,"name":"number","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3,"src":"214:6:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"209:11:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":10,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"201:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":14,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"201:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":15,"nodeType":"ExpressionStatement","src":"201:20:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":19,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"3230","id":17,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"239:2:0","typeDescriptions":{"typeIdentifier":"t_rational_20_by_1","typeString":"int_const 20"},"value":"20"},"nodeType":"BinaryOperation","operator":">","rightExpression":{"id":18,"name":"number","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3,"src":"244:6:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"239:11:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":16,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"231:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":20,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"231:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":21,"nodeType":"ExpressionStatement","src":"231:20:0"}]},"functionSelector":"d09de08a","implemented":true,"kind":"function","modifiers":[],"name":"increment","nameLocation":"172:9:0","parameters":{"id":8,"nodeType":"ParameterList","parameters":[],"src":"181:2:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[],"src":"191:0:0"},"scope":24,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"Counter1","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[24],"name":"Counter1","nameLocation":"66:8:0","scope":25,"usedErrors":[]}],"license":"MIT"} \ No newline at end of file +{"absolutePath":"src/contract.sol","id":12,"exportedSymbols":{"Counter1":[11]},"nodeType":"SourceUnit","src":"32:159:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".12"]},{"id":11,"nodeType":"ContractDefinition","src":"57:132:0","nodes":[{"id":10,"nodeType":"StructDefinition","src":"84:102:0","nodes":[],"canonicalName":"Counter1.red","members":[{"constant":false,"id":3,"mutability":"mutable","name":"errrr","nameLocation":"110:5:0","nodeType":"VariableDeclaration","scope":10,"src":"105:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2,"name":"uint","nodeType":"ElementaryTypeName","src":"105:4:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"unite","nameLocation":"132:5:0","nodeType":"VariableDeclaration","scope":10,"src":"125:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"},"typeName":{"id":4,"name":"string","nodeType":"ElementaryTypeName","src":"125:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":7,"mutability":"mutable","name":"ras3","nameLocation":"153:4:0","nodeType":"VariableDeclaration","scope":10,"src":"147:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"},"typeName":{"id":6,"name":"uint8","nodeType":"ElementaryTypeName","src":"147:5:0","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"visibility":"internal"},{"constant":false,"id":9,"mutability":"mutable","name":"dear","nameLocation":"175:4:0","nodeType":"VariableDeclaration","scope":10,"src":"167:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes20","typeString":"bytes20"},"typeName":{"id":8,"name":"bytes20","nodeType":"ElementaryTypeName","src":"167:7:0","typeDescriptions":{"typeIdentifier":"t_bytes20","typeString":"bytes20"}},"visibility":"internal"}],"name":"red","nameLocation":"91:3:0","scope":11,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"Counter1","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[11],"name":"Counter1","nameLocation":"66:8:0","scope":12,"usedErrors":[]}],"license":"MIT"} \ No newline at end of file diff --git a/src/optimizor/ast.rs b/src/optimizor/ast.rs index d561e62..d5aae26 100644 --- a/src/optimizor/ast.rs +++ b/src/optimizor/ast.rs @@ -1,19 +1,17 @@ -use std::fs; use ethers_solc; -use ethers_solc::{Project}; +use ethers_solc::Project; +use std::fs; pub fn ast() { - // create a project from a configuration file - let project = Project::builder().build().unwrap(); - let output = project - .compile_files(vec!["src/contract.sol"]) - .unwrap(); - let artifacts = output.output().sources.0; - let mut s_ast = artifacts.values(); - let mut binding = s_ast.next(); - let mut binding = binding.iter_mut().next(); - let s_asts = binding.as_mut().unwrap(); - let ast = s_asts.get(0).unwrap().source_file.ast.clone().unwrap(); - let ast_json = serde_json::to_string(&ast).unwrap(); - fs::write("src/optimizor/ast.json", ast_json).expect("failed to write ast"); -} \ No newline at end of file + // create a project from a configuration file + let project = Project::builder().build().unwrap(); + let output = project.compile_files(vec!["src/contract.sol"]).unwrap(); + let artifacts = output.output().sources.0; + let mut s_ast = artifacts.values(); + let mut binding = s_ast.next(); + let mut binding = binding.iter_mut().next(); + let s_asts = binding.as_mut().unwrap(); + let ast = s_asts.get(0).unwrap().source_file.ast.clone().unwrap(); + let ast_json = serde_json::to_string(&ast).unwrap(); + fs::write("src/optimizor/ast.json", ast_json).expect("failed to write ast"); +} diff --git a/src/optimizor/bytes32.rs b/src/optimizor/bytes32.rs index 70c87fc..13261c5 100644 --- a/src/optimizor/bytes32.rs +++ b/src/optimizor/bytes32.rs @@ -41,4 +41,4 @@ pub fn bytes32(contract: &str, gas_inefficiencies: &mut Map usize { _prev = line_number + 1; break; } - times = times + 1; + times += 1; } } } diff --git a/src/optimizor/constructor_check_absence.rs b/src/optimizor/constructor_check_absence.rs index 0fcd908..d09022b 100644 --- a/src/optimizor/constructor_check_absence.rs +++ b/src/optimizor/constructor_check_absence.rs @@ -1,6 +1,4 @@ use regex::Regex; -use serde_json::json; -use serde_json::Map; pub fn check_constructor_absence(contract: &str) { let constructor_regex = Regex::new(r"constructor\s*\(.*\)").unwrap(); diff --git a/src/optimizor/do_while.rs b/src/optimizor/do_while.rs index d946543..87f78ec 100644 --- a/src/optimizor/do_while.rs +++ b/src/optimizor/do_while.rs @@ -27,4 +27,4 @@ pub fn do_while(contract: &str, gas_inefficiencies: &mut Map = serde_json::from_value(existing_value.clone()).unwrap_or_default(); - existing_arr.push( - "Use mapping instead of array: Modifier:" - .to_string(), - ); + existing_arr.push("Use mapping instead of array: Modifier:".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![ - "Use mapping instead of array: Modifier:", - ]; + let new_arr = vec!["Use mapping instead of array: Modifier:"]; gas_inefficiencies.insert(inefficiency_id, json!(new_arr)); } println!("Use mapping instead of array: Modifier:"); } } -} \ No newline at end of file +} diff --git a/src/optimizor/mod.rs b/src/optimizor/mod.rs index 66ceb8e..086b432 100644 --- a/src/optimizor/mod.rs +++ b/src/optimizor/mod.rs @@ -1,18 +1,19 @@ pub mod ast; -pub mod token; pub mod bytes32; -pub mod safemath; -pub mod openzeppelin; -pub mod revert_32; +pub mod cache_state_variables; +pub mod constructor_check_absence; pub mod do_while; pub mod emit_loops; -pub mod write_zero_to_storage; -pub mod cache_state_variables; -pub mod uint256_instead_bool; -pub mod require_double_logic; pub mod mapping_instead_array; -pub mod priv_constants_immut; +pub mod openzeppelin; pub mod pack_related_vars; -pub mod use_named_returns; +pub mod priv_constants_immut; +pub mod require_double_logic; +pub mod revert_32; +pub mod safemath; +pub mod struct_packing; +pub mod token; +pub mod uint256_instead_bool; pub mod uint_incur_overhead; -pub mod constructor_check_absence; \ No newline at end of file +pub mod use_named_returns; +pub mod write_zero_to_storage; diff --git a/src/optimizor/openzeppelin.rs b/src/optimizor/openzeppelin.rs index e4f6c9c..6f7670a 100644 --- a/src/optimizor/openzeppelin.rs +++ b/src/optimizor/openzeppelin.rs @@ -2,7 +2,6 @@ use regex::Regex; use serde_json::json; use serde_json::Map; - pub fn openzepplin(contract: &str, gas_inefficiencies: &mut Map) { let variable_declaration_regex = Regex::new(r"openzeppelin").unwrap(); diff --git a/src/optimizor/pack_related_vars.rs b/src/optimizor/pack_related_vars.rs index e69de29..8b13789 100644 --- a/src/optimizor/pack_related_vars.rs +++ b/src/optimizor/pack_related_vars.rs @@ -0,0 +1 @@ + diff --git a/src/optimizor/priv_constants_immut.rs b/src/optimizor/priv_constants_immut.rs index 69b83c1..c0e41e0 100644 --- a/src/optimizor/priv_constants_immut.rs +++ b/src/optimizor/priv_constants_immut.rs @@ -31,4 +31,4 @@ pub fn priv_constants_immut( println!("variables that are constant should have a visibility of private"); } } -} \ No newline at end of file +} diff --git a/src/optimizor/safemath.rs b/src/optimizor/safemath.rs index 1a498d6..bb31601 100644 --- a/src/optimizor/safemath.rs +++ b/src/optimizor/safemath.rs @@ -2,7 +2,6 @@ use regex::Regex; use serde_json::json; use serde_json::Map; - pub fn safemath(contract: &str, gas_inefficiencies: &mut Map) { let variable_declaration_regex = Regex::new(r"SafeMath").unwrap(); diff --git a/src/optimizor/struct_packing.rs b/src/optimizor/struct_packing.rs new file mode 100644 index 0000000..d20b4dd --- /dev/null +++ b/src/optimizor/struct_packing.rs @@ -0,0 +1,72 @@ +use crate::utils::{extract_struct_node, number_to_types, update_gas_ineffiency_map}; +use regex::Regex; +use serde_json::Map; +use std::fs; + +pub fn struct_packing(gas_inefficiencies: &mut Map, mut _prev: usize) { + let mut _name = ""; + let (old_arr, _name) = extract_struct_node::extract_struct_node(); + let mut old_arrs: Vec = Vec::new(); + let mut new_arr: Vec = Vec::new(); + let mut new_arr_str: Vec = Vec::new(); + + for str_to_f64 in old_arr { + if let Ok(parsed_number) = str_to_f64.parse::() { + new_arr.push(parsed_number); + old_arrs.push(parsed_number); + new_arr.sort_by(|a, b| a.partial_cmp(b).unwrap()); + } + } + + //Update gas_inefficiencies map + for str_new_arr in new_arr.clone() { + new_arr_str.push( + number_to_types::number_to_types() + .get(&str_new_arr.to_string()) + .unwrap() + .to_string().trim_matches('"').to_string(), + ); + } + + if old_arrs != new_arr { + println!("{:?}", true); + _prev = get_line_number_zero(_name.as_str(), _prev); + let mut _inefficiency_id = format!("line_{}", get_line_number_zero(_name.as_str(), _prev)); + + get_line_number_zero(_name.as_str(), _prev); + _inefficiency_id = format!("line_{}", _prev); + + update_gas_ineffiency_map::update_gas_inefficency_map( + _inefficiency_id, + gas_inefficiencies, + format!( + "struct is arraged wrongly should be arranged in this way {:?}", + new_arr_str + ), + ) + } +} + +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!(r"struct {}", src); + + // Compile the regex pattern + let variable_declaration_regex = Regex::new(&strss).unwrap(); + + 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 +} diff --git a/src/optimizor/uint256_instead_bool.rs b/src/optimizor/uint256_instead_bool.rs index 9d63527..f1e4375 100644 --- a/src/optimizor/uint256_instead_bool.rs +++ b/src/optimizor/uint256_instead_bool.rs @@ -21,22 +21,18 @@ pub fn uint256_instead_bool( let mut existing_arr: Vec = serde_json::from_value(existing_value.clone()).unwrap_or_default(); - existing_arr.push( - "Use uint256 type to store boolean value instead of bool" - .to_string(), - ); + existing_arr + .push("Use uint256 type to store boolean value instead of bool".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![ - "Use uint256 type to store boolean value instead of bool", - ]; + let new_arr = vec!["Use uint256 type to store boolean value instead of bool"]; gas_inefficiencies.insert(inefficiency_id, json!(new_arr)); } println!("Use uint256 type to store boolean value instead of bool"); } } -} \ No newline at end of file +} diff --git a/src/optimizor/uint_incur_overhead.rs b/src/optimizor/uint_incur_overhead.rs index 4e8b646..b40e67d 100644 --- a/src/optimizor/uint_incur_overhead.rs +++ b/src/optimizor/uint_incur_overhead.rs @@ -2,7 +2,6 @@ use regex::Regex; use serde_json::json; use serde_json::Map; - pub fn uint_incur_overhead( contract: &str, gas_inefficiencies: &mut Map, diff --git a/src/optimizor/use_named_returns.rs b/src/optimizor/use_named_returns.rs index 2600560..76d6476 100644 --- a/src/optimizor/use_named_returns.rs +++ b/src/optimizor/use_named_returns.rs @@ -18,16 +18,13 @@ pub fn use_named_retunrs(contract: &str, gas_inefficiencies: &mut Map = serde_json::from_value(existing_value.clone()).unwrap_or_default(); - existing_arr.push( - "Use named returns".to_string(), - ); + existing_arr.push("Use named returns".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!["Use named returns"]; + let new_arr = vec!["Use named returns"]; gas_inefficiencies.insert(inefficiency_id, json!(new_arr)); } println!("Use named returns"); diff --git a/src/optimizor/write_zero_to_storage.rs b/src/optimizor/write_zero_to_storage.rs index ffd014b..9cb2441 100644 --- a/src/optimizor/write_zero_to_storage.rs +++ b/src/optimizor/write_zero_to_storage.rs @@ -1,11 +1,13 @@ use regex::Regex; -use serde_json::Map; use serde_json::json; +use serde_json::Map; use serde_json::Value; use std::fs; - -pub fn write_zero_to_storage(gas_inefficiencies: &mut Map, mut _prev: usize) { +pub fn write_zero_to_storage( + gas_inefficiencies: &mut Map, + 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 = ""; @@ -52,11 +54,19 @@ pub fn write_zero_to_storage(gas_inefficiencies: &mut Map usize { // Compile the regex pattern let variable_declaration_regex = Regex::new(&strss).unwrap(); - 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; + _prev = line_number + 1; break; } - } } _prev diff --git a/src/utils/data_types.rs b/src/utils/data_types.rs new file mode 100644 index 0000000..9b3c473 --- /dev/null +++ b/src/utils/data_types.rs @@ -0,0 +1,44 @@ +#[warn(dead_code)] + +pub enum SolDataTypes { + Strings, // Variable-length byte array + Uint8, // Unsigned integer of 8 bits + Uint16, // Unsigned integer of 16 bits + Uint160, // Unsigned integer of 160 bits + Uint256, // Unsigned integer of 256 bits + Uint, // Unsigned integer of 256 bits (assuming this is a placeholder) + Bytes4, // Fixed-length byte array of 4 bytes + Bytes20, // Fixed-length byte array of 20 bytes + Bytes32, // Fixed-length byte array of 32 bytes + Bytes, // Dynamic-length byte array + Bool, // Boolean value, true or false + Address, // 160-bit value that can store an Ethereum address + Int8, // Signed integer of 8 bits + Int16, // Signed integer of 16 bits + Int256, // Signed integer of 256 bits + Int, // Signed integer of 256 bits (assuming this is a placeholder) +} + +impl SolDataTypes { + pub fn to_string_representation(&self) -> &'static str { + match self { + SolDataTypes::Strings => "string", + SolDataTypes::Uint8 => "uint8", + SolDataTypes::Uint16 => "uint16", + SolDataTypes::Uint160 => "uint160", + SolDataTypes::Uint256 => "uint256", + SolDataTypes::Uint => "uint", + SolDataTypes::Bytes4 => "bytes4", + SolDataTypes::Bytes20 => "bytes20", + SolDataTypes::Bytes32 => "bytes32", + SolDataTypes::Bytes => "bytes", + SolDataTypes::Bool => "bool", + SolDataTypes::Address => "address", + SolDataTypes::Int8 => "int8", + SolDataTypes::Int16 => "int16", + SolDataTypes::Int256 => "int256", + SolDataTypes::Int => "int", + } + } +} + diff --git a/src/utils/extract_struct_node.rs b/src/utils/extract_struct_node.rs new file mode 100644 index 0000000..35f4f8d --- /dev/null +++ b/src/utils/extract_struct_node.rs @@ -0,0 +1,56 @@ +use crate::utils::{types_to_numbers}; +use serde_json::{Value}; +use std::fs; + +pub fn extract_struct_node() -> (Vec, String) { + 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 arr = Vec::new(); + let mut name = ""; + 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) { + if node_type == "ContractDefinition" { + + if let Some(contract_nodes) = node.get("nodes").and_then(Value::as_array) { + for contract_node in contract_nodes { + + if let Some(func_node) = contract_node.as_object() { + if func_node.get("nodeType").and_then(Value::as_str) + == Some("StructDefinition") + { + name = func_node.get("name").unwrap().as_str().unwrap(); + if let Some(members) = + func_node.get("members").and_then(Value::as_array) + { + for member in members { + if let Some(type_name) = member.get("typeName") { + if let Some(name) = + type_name.get("name").and_then(Value::as_str) + { + let t_to_n = types_to_numbers::_types_to_number(); + if let Some(val) = + t_to_n.get(name).and_then(|v| v.as_str()) + { + arr.push(val.to_string()); + // Clone and push the value + } else { + // Handle the case when the value is not found or not a string + println!("Warning: Value not found or not a string for name '{}'", name); + } + } + } + } + } + } + } + } + } + } + } + } + } + (arr, name.to_owned()) +} + diff --git a/src/utils/get_all_state_var.rs b/src/utils/get_all_state_var.rs index a931ff5..e85fb8a 100644 --- a/src/utils/get_all_state_var.rs +++ b/src/utils/get_all_state_var.rs @@ -1,6 +1,6 @@ +use serde_json; use serde_json::Value; use std::fs; -use serde_json; pub fn get_all_state_vars() -> serde_json::Map { let ast_json = fs::read_to_string("src/optimizor/ast.json").expect("Failed to read"); @@ -21,9 +21,15 @@ pub fn get_all_state_vars() -> serde_json::Map { && state_node.get("stateVariable").and_then(Value::as_bool) == Some(true) { - obj.insert(state_node.get("name").unwrap().as_str().unwrap().to_owned(), - serde_json::to_value(true).unwrap()); - + obj.insert( + state_node + .get("name") + .unwrap() + .as_str() + .unwrap() + .to_owned(), + serde_json::to_value(true).unwrap(), + ); } } } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index fbd3eb2..72f8deb 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,2 +1,6 @@ pub mod get_all_state_var; -pub mod update_gas_ineffiency_map; \ No newline at end of file +pub mod update_gas_ineffiency_map; +pub mod data_types; +pub mod types_to_numbers; +pub mod number_to_types; +pub mod extract_struct_node; \ No newline at end of file diff --git a/src/utils/number_to_types.rs b/src/utils/number_to_types.rs new file mode 100644 index 0000000..6881e60 --- /dev/null +++ b/src/utils/number_to_types.rs @@ -0,0 +1,72 @@ +use crate::utils::data_types::SolDataTypes; +use serde_json::{json, Map, Value}; + +pub fn number_to_types() -> Map { + let mut map: Map = Map::new(); + + map.insert( + "1".to_string(), + json!(SolDataTypes::Bool.to_string_representation()), + ); + map.insert( + "1.1".to_string(), + json!(SolDataTypes::Bytes4.to_string_representation()), + ); + map.insert( + "1.2".to_string(), + json!(SolDataTypes::Uint8.to_string_representation()), + ); + map.insert( + "1.3".to_string(), + json!(SolDataTypes::Int8.to_string_representation()), + ); + map.insert( + "2".to_string(), + json!(SolDataTypes::Int16.to_string_representation()), + ); + map.insert( + "2.1".to_string(), + json!(SolDataTypes::Uint16.to_string_representation()), + ); + map.insert( + "3".to_string(), + json!(SolDataTypes::Address.to_string_representation()), + ); + map.insert( + "3.1".to_string(), + json!(SolDataTypes::Uint160.to_string_representation()), + ); + map.insert( + "3.2".to_string(), + json!(SolDataTypes::Bytes20.to_string_representation()), + ); + map.insert( + "4".to_string(), + json!(SolDataTypes::Uint.to_string_representation()), + ); + map.insert( + "4.1".to_string(), + json!(SolDataTypes::Uint256.to_string_representation()), + ); + map.insert( + "4.2".to_string(), + json!(SolDataTypes::Bytes32.to_string_representation()), + ); + map.insert( + "4.3".to_string(), + json!(SolDataTypes::Int.to_string_representation()), + ); + map.insert( + "4.4".to_string(), + json!(SolDataTypes::Int256.to_string_representation()), + ); + map.insert( + "5".to_string(), + json!(SolDataTypes::Strings.to_string_representation()), + ); + map.insert( + "5.1".to_string(), + json!(SolDataTypes::Bytes.to_string_representation()), + ); + map +} diff --git a/src/utils/types_to_numbers.rs b/src/utils/types_to_numbers.rs new file mode 100644 index 0000000..08154b1 --- /dev/null +++ b/src/utils/types_to_numbers.rs @@ -0,0 +1,74 @@ +use crate::utils::data_types::SolDataTypes; +use serde_json::{json, Map, Value}; + + +pub fn _types_to_number() -> Map { + let mut map: Map = Map::new(); + + // Adding an entry for all data_types to map + map.insert( + SolDataTypes::Bool.to_string_representation().to_string(), + json!("1"), + ); + map.insert( + SolDataTypes::Bytes4.to_string_representation().to_string(), + json!("1.1"), + ); + map.insert( + SolDataTypes::Uint8.to_string_representation().to_string(), + json!("1.2"), + ); + map.insert( + SolDataTypes::Int8.to_string_representation().to_string(), + json!("1.3"), + ); + map.insert( + SolDataTypes::Int16.to_string_representation().to_string(), + json!("2"), + ); + map.insert( + SolDataTypes::Uint16.to_string_representation().to_string(), + json!("2.1"), + ); + map.insert( + SolDataTypes::Address.to_string_representation().to_string(), + json!("3"), + ); + map.insert( + SolDataTypes::Uint160.to_string_representation().to_string(), + json!("3.1"), + ); + map.insert( + SolDataTypes::Bytes20.to_string_representation().to_string(), + json!("3.2"), + ); + map.insert( + SolDataTypes::Uint.to_string_representation().to_string(), + json!("4"), + ); + map.insert( + SolDataTypes::Uint256.to_string_representation().to_string(), + json!("4.1"), + ); + map.insert( + SolDataTypes::Bytes32.to_string_representation().to_string(), + json!("4.2"), + ); + map.insert( + SolDataTypes::Int.to_string_representation().to_string(), + json!("4.3"), + ); + map.insert( + SolDataTypes::Int256.to_string_representation().to_string(), + json!("4.4"), + ); + map.insert( + SolDataTypes::Strings.to_string_representation().to_string(), + json!("5"), + ); + map.insert( + SolDataTypes::Bytes.to_string_representation().to_string(), + json!("5.1"), + ); + map +} diff --git a/src/utils/update_gas_ineffiency_map.rs b/src/utils/update_gas_ineffiency_map.rs index 36ada25..c16c405 100644 --- a/src/utils/update_gas_ineffiency_map.rs +++ b/src/utils/update_gas_ineffiency_map.rs @@ -1,7 +1,11 @@ use serde_json::json; use serde_json::Map; -pub fn update_gas_inefficency_map(inefficiency_id: String, gas_inefficiencies: &mut Map, err: String) { +pub fn update_gas_inefficency_map( + inefficiency_id: String, + gas_inefficiencies: &mut Map, + err: String, +) { // 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 diff --git a/tests/gas_tricks_test.rs b/tests/gas_tricks_test.rs index e419b0e..44bf10a 100644 --- a/tests/gas_tricks_test.rs +++ b/tests/gas_tricks_test.rs @@ -15,9 +15,9 @@ // mod tests { // use super::*; - + // mod src { - + // } // #[test] @@ -56,5 +56,4 @@ // optimizor::gas_tricks::check_constructor_absence(contract); // } - // }