Skip to content

Commit 95c3ed4

Browse files
committed
Removed unused methods, rewritten error prints, added new checks in SmartContract
1 parent bfc740f commit 95c3ed4

File tree

3 files changed

+58
-93
lines changed

3 files changed

+58
-93
lines changed

src/main/java/it/unipr/EVMLiSA.java

Lines changed: 33 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,8 @@ public static void setTestMode() {
145145
* Executes the analysis workflow.
146146
*
147147
* @param args command-line arguments
148-
*
149-
* @throws Exception if an error occurs during execution
150148
*/
151-
private void go(String[] args) throws Exception {
149+
private void go(String[] args) {
152150
CommandLine cmd = parseCommandLine(args);
153151
if (cmd == null)
154152
return;
@@ -194,7 +192,6 @@ else if (cmd.hasOption("bytecode"))
194192
.setBytecode(cmd.getOptionValue("bytecode"));
195193

196194
else {
197-
log.error("No valid option provided.");
198195
JSONManager.throwNewError("No valid option provided.");
199196
System.exit(1);
200197
}
@@ -207,13 +204,21 @@ else if (cmd.hasOption("bytecode"))
207204
* Analyzes a set of smart contracts from a given file.
208205
*
209206
* @param filePath the path to the file containing contract addresses
210-
*
211-
* @throws Exception if an error occurs during analysis
212207
*/
213-
public static void analyzeSetOfContracts(Path filePath) throws Exception {
214-
log.info("Analyzing set of contracts...");
215-
208+
public static void analyzeSetOfContracts(Path filePath) {
209+
log.info("Building contracts...");
216210
List<SmartContract> contracts = buildContractsFromFile(filePath);
211+
analyzeSetOfContracts(contracts);
212+
}
213+
214+
/**
215+
* Analyzes a set of smart contracts from a list of {@link SmartContract}.
216+
*
217+
* @param contracts the list of {@link SmartContract} to be analyzed
218+
*/
219+
public static void analyzeSetOfContracts(List<SmartContract> contracts) {
220+
log.info("Analyzing {} contracts...", contracts.size());
221+
217222
ExecutorService executor = Executors.newFixedThreadPool(CORES);
218223
List<Future<?>> futures = new ArrayList<>();
219224

@@ -225,7 +230,7 @@ public static void analyzeSetOfContracts(Path filePath) throws Exception {
225230
waitForCompletion(futures);
226231

227232
executor.shutdown();
228-
log.info("Finished analyzing {} contracts.", contracts.size());
233+
log.info("Finished analysis of {} contracts.", contracts.size());
229234

230235
Path outputDir = OUTPUT_DIRECTORY_PATH.resolve("set-of-contracts");
231236
try {
@@ -236,7 +241,8 @@ public static void analyzeSetOfContracts(Path filePath) throws Exception {
236241
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
237242
log.info("Results saved in {}", outputDir.resolve("results.json"));
238243
} catch (IOException e) {
239-
log.error("Failed to save results in {}", outputDir, e);
244+
System.err.println(JSONManager.throwNewError("Failed to save results in " + outputDir));
245+
System.exit(1);
240246
}
241247
}
242248

@@ -246,19 +252,15 @@ public static void analyzeSetOfContracts(Path filePath) throws Exception {
246252
* @param contract the smart contract to analyze
247253
*/
248254
public static void analyzeContract(SmartContract contract) {
249-
if (TEST_MODE) {
250-
analyzeContractInTestMode(contract);
251-
return;
252-
}
253-
254255
log.info("Analyzing contract {}...", contract.getAddress());
255256

256-
Program program;
257+
Program program = null;
257258
try {
258259
program = EVMFrontend.generateCfgFromFile(contract.getMnemonicBytecodePath().toString());
259260
} catch (IOException e) {
260-
log.error("Unable to generate CFG from file");
261-
return;
261+
System.err.println(
262+
JSONManager.throwNewError("Unable to generate partial CFG from file", contract.toJson()));
263+
System.exit(1);
262264
}
263265

264266
LiSAConfiguration conf = LiSAConfigurationManager.createConfiguration(contract);
@@ -272,8 +274,11 @@ public static void analyzeContract(SmartContract contract) {
272274

273275
contract.setStatistics(
274276
computeStatistics(checker, lisa, program));
275-
276277
contract.setCFG(checker.getComputedCFG());
278+
279+
if (TEST_MODE)
280+
return;
281+
277282
contract.computeFunctionsSignatureEntryPoints();
278283
contract.computeFunctionsSignatureExitPoints();
279284
contract.computeEventsSignatureEntryPoints();
@@ -321,67 +326,6 @@ public static void analyzeContract(SmartContract contract) {
321326
contract.toFile();
322327
}
323328

324-
/**
325-
* Analyzes a given smart contract in test mode (i.e., without computing
326-
* functions, events).
327-
*
328-
* @param contract the smart contract to analyze
329-
*/
330-
public static void analyzeContractInTestMode(SmartContract contract) {
331-
log.info("Analyzing contract {}...", contract.getAddress());
332-
333-
Program program;
334-
try {
335-
program = EVMFrontend.generateCfgFromFile(contract.getMnemonicBytecodePath().toString());
336-
} catch (IOException e) {
337-
log.error("Unable to generate CFG from file");
338-
return;
339-
}
340-
341-
LiSAConfiguration conf = LiSAConfigurationManager.createConfiguration(contract);
342-
JumpSolver checker = new JumpSolver();
343-
conf.semanticChecks.add(checker);
344-
345-
LiSA lisa = new LiSA(conf);
346-
lisa.run(program);
347-
348-
log.info("Analysis ended ({})", contract.getAddress());
349-
350-
contract.setStatistics(
351-
computeStatistics(checker, lisa, program));
352-
}
353-
354-
/**
355-
* Analyzes a given smart contract in test mode (i.e., without producing
356-
* output files).
357-
*
358-
* @param contract the smart contract to analyze
359-
*/
360-
public static void analyzeContractInWebAppMode(SmartContract contract) {
361-
Program program;
362-
try {
363-
program = EVMFrontend.generateCfgFromFile(contract.getMnemonicBytecodePath().toString());
364-
} catch (IOException e) {
365-
log.error("Unable to generate CFG from file");
366-
return;
367-
}
368-
369-
LiSAConfiguration conf = LiSAConfigurationManager.createConfigurationForWebApp(contract);
370-
JumpSolver checker = new JumpSolver();
371-
conf.semanticChecks.add(checker);
372-
373-
LiSA lisa = new LiSA(conf);
374-
lisa.run(program);
375-
376-
contract.setStatistics(
377-
computeStatistics(checker, lisa, program));
378-
contract.setCFG(checker.getComputedCFG());
379-
contract.computeFunctionsSignatureEntryPoints();
380-
contract.computeFunctionsSignatureExitPoints();
381-
contract.computeEventsSignatureEntryPoints();
382-
contract.computeEventsExitPoints();
383-
}
384-
385329
/**
386330
* Computes statistics based on the analysis of jumps within the given
387331
* program.
@@ -551,10 +495,8 @@ private static Set<Statement> getSoundlySolvedJumps(JumpSolver checker, LiSA lis
551495
* @param filePath the path to the file containing contract addresses
552496
*
553497
* @return a list of {@link SmartContract} objects
554-
*
555-
* @throws Exception if an error occurs while reading the file
556498
*/
557-
public static List<SmartContract> buildContractsFromFile(Path filePath) throws Exception {
499+
public static List<SmartContract> buildContractsFromFile(Path filePath) {
558500
log.info("Parsing contracts from {}", filePath);
559501

560502
List<SmartContract> contracts = new ArrayList<>();
@@ -572,8 +514,8 @@ public static List<SmartContract> buildContractsFromFile(Path filePath) throws E
572514
myReader.close();
573515

574516
} catch (FileNotFoundException e) {
575-
log.error("{} not found.", filePath);
576-
throw e;
517+
JSONManager.throwNewError("Unable to read " + filePath + ". File not found.");
518+
System.exit(1);
577519
}
578520

579521
log.info("Created {} contracts.", contracts.size());
@@ -608,7 +550,7 @@ private void setupGlobalOptions(CommandLine cmd) {
608550
if (cmd.hasOption("stack-set-size"))
609551
AbstractStackSet.setStackSetSize(Integer.parseInt(cmd.getOptionValue("stack-set-size")));
610552
} catch (NumberFormatException e) {
611-
log.error("Size must be an integer.");
553+
System.err.println(JSONManager.throwNewError("Size must be an integer."));
612554
System.exit(1);
613555
}
614556

@@ -782,9 +724,11 @@ static private void waitForCompletion(List<Future<?>> futures) {
782724
try {
783725
future.get();
784726
} catch (ExecutionException e) {
785-
log.error("Error during task execution: {}", e.getMessage());
727+
System.err.println(JSONManager.throwNewError("Error during task execution: " + e.getMessage()));
728+
System.exit(1);
786729
} catch (InterruptedException ie) {
787-
log.error("Interrupted during task execution: {}", ie.getMessage());
730+
System.err.println(JSONManager.throwNewError("Interrupted during task execution: " + ie.getMessage()));
731+
System.exit(1);
788732
}
789733
}
790734
}

src/main/java/it/unipr/analysis/contract/SmartContract.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public SmartContract(String address) {
120120
if (!file.exists()) {
121121
Thread.sleep(500); // Etherscan API request limit
122122
Files.createDirectories(outputDir);
123+
123124
this._bytecode = EVMFrontend.parseBytecodeFromEtherscan(address);
124125
// Write bytecode to file
125126
if (this._bytecode != null)
@@ -144,12 +145,13 @@ public SmartContract(String address) {
144145
File file = new File(String.valueOf(_abiFilePath));
145146
if (!file.exists()) {
146147
Thread.sleep(500); // Etherscan API request limit
148+
147149
Files.createDirectories(outputDir);
148150
this._abi = EVMFrontend.parseABIFromEtherscan(address);
151+
149152
// Write ABI to file
150-
if (this._abi != null)
151-
Files.writeString(this._abiFilePath, this._abi.toString(4), StandardOpenOption.CREATE,
152-
StandardOpenOption.TRUNCATE_EXISTING);
153+
Files.writeString(this._abiFilePath, this._abi.toString(4), StandardOpenOption.CREATE,
154+
StandardOpenOption.TRUNCATE_EXISTING);
153155
} else {
154156
log.warn("Contract (ABI) already present in {}, not downloaded.", _abiFilePath);
155157
this._abi = new JSONArray(new String(Files.readAllBytes(Paths.get(_abiFilePath.toString()))));
@@ -423,11 +425,16 @@ public SmartContract setAbi(JSONArray abi) {
423425
/**
424426
* Sets the control flow graph and extracts basic blocks.
425427
*
426-
* @param cfg The EVMCFG to set.
428+
* @param cfg The {@link EVMCFG} to set.
427429
*
428430
* @return This SmartContract instance for method chaining.
429431
*/
430432
public SmartContract setCFG(EVMCFG cfg) {
433+
if (cfg == null) {
434+
System.err.println(JSONManager.throwNewError("CFG cannot be null"));
435+
System.exit(1);
436+
}
437+
431438
this._cfg = cfg;
432439
this._basicBlocks = BasicBlock.getBasicBlocks(cfg);
433440
return this;

src/main/java/it/unipr/utils/JSONManager.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,18 @@ public static JSONObject throwNewError(String error) {
207207
errorJson.put("error", error);
208208
return errorJson;
209209
}
210+
211+
public static JSONObject throwNewError(String error, String notes) {
212+
JSONObject errorJson = new JSONObject();
213+
errorJson.put("error", error);
214+
errorJson.put("notes", notes);
215+
return errorJson;
216+
}
217+
218+
public static JSONObject throwNewError(String error, JSONObject notes) {
219+
JSONObject errorJson = new JSONObject();
220+
errorJson.put("error", error);
221+
errorJson.put("notes", notes);
222+
return errorJson;
223+
}
210224
}

0 commit comments

Comments
 (0)