Skip to content

Commit 5c8e10a

Browse files
committed
Added cross-chain analysis' option
1 parent 014f5e1 commit 5c8e10a

File tree

1 file changed

+118
-1
lines changed

1 file changed

+118
-1
lines changed

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

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import it.unipr.checker.JumpSolver;
77
import it.unipr.checker.ReentrancyChecker;
88
import it.unipr.checker.TxOriginChecker;
9+
import it.unipr.crossChainAnalysis.BridgeAnalysis;
910
import it.unipr.frontend.EVMFrontend;
1011
import it.unive.lisa.LiSA;
1112
import it.unive.lisa.analysis.SimpleAbstractState;
@@ -88,6 +89,15 @@ private void go(String[] args) throws Exception {
8889
if (cmd == null)
8990
return;
9091

92+
// Cross chain analysis
93+
if (cmd.hasOption("cross-chain-abi") && cmd.hasOption("cross-chain-bytecode")) {
94+
new BridgeAnalysis(
95+
Path.of(cmd.getOptionValue("cross-chain-abi")),
96+
Path.of(cmd.getOptionValue("cross-chain-bytecode")))
97+
.run();
98+
return;
99+
}
100+
91101
// Ensure that at least one valid option is provided to specify the
92102
// bytecode source
93103
if (!cmd.hasOption("address") && !cmd.hasOption("filepath-bytecode") && !cmd.hasOption("mnemonic-bytecode")) {
@@ -176,6 +186,16 @@ private void go(String[] args) throws Exception {
176186
}
177187
}
178188

189+
/**
190+
* This method sets up the available options and attempts to parse the
191+
* provided arguments. If parsing fails, it logs the error, prints the help
192+
* message, and terminates the program.
193+
*
194+
* @param args The command-line arguments to be parsed.
195+
*
196+
* @return A {@link CommandLine} object containing the parsed options, or
197+
* {@code null} if parsing fails.
198+
*/
179199
private CommandLine parseCommandLine(String[] args) {
180200
Options options = getOptions();
181201
CommandLineParser parser = new DefaultParser();
@@ -191,6 +211,12 @@ private CommandLine parseCommandLine(String[] args) {
191211
}
192212
}
193213

214+
/**
215+
* Configures global options based on the parsed command-line arguments.
216+
*
217+
* @param cmd The parsed {@link CommandLine} object containing the provided
218+
* options.
219+
*/
194220
private void setupGlobalOptions(CommandLine cmd) {
195221
try {
196222
CORES = cmd.hasOption("cores") ? Integer.parseInt(cmd.getOptionValue("cores")) : 1;
@@ -221,6 +247,13 @@ private void setupGlobalOptions(CommandLine cmd) {
221247
EVMAbstractState.setUseStorageLive();
222248
}
223249

250+
/**
251+
* Configures the output directories based on the parsed command-line
252+
* arguments.
253+
*
254+
* @param cmd The parsed {@link CommandLine} object containing the provided
255+
* options.
256+
*/
224257
private void setupOutputDirectories(CommandLine cmd) {
225258
if (cmd.hasOption("output")) {
226259
_outputDirPath = Paths.get(cmd.getOptionValue("output"));
@@ -232,6 +265,15 @@ private void setupOutputDirectories(CommandLine cmd) {
232265
}
233266
}
234267

268+
/**
269+
* Sets up a JSONObject with the values derived from the command line
270+
* options. The method collects the options related to the execution and
271+
* populates them into a JSON object.
272+
*
273+
* @param cmd The command line object containing the options.
274+
*
275+
* @return A JSONObject containing the options parsed from the command line.
276+
*/
235277
private JSONObject setupJSON(CommandLine cmd) {
236278
JSONObject jsonOptions = new JSONObject();
237279
jsonOptions.put("address", cmd.getOptionValue("address"));
@@ -256,6 +298,17 @@ private JSONObject setupJSON(CommandLine cmd) {
256298
return jsonOptions;
257299
}
258300

301+
/**
302+
* Sets up the benchmark environment by creating necessary directories and
303+
* setting file paths for the benchmark data (such as statistics, logs, and
304+
* failures). The method generates file paths based on the current timestamp
305+
* and stack limits, and attempts to create the necessary directories for
306+
* saving benchmark results.
307+
*
308+
* @param benchmarkPath The path to the benchmark file to be processed.
309+
* @param json A JSONObject containing the configuration options
310+
* for the benchmark.
311+
*/
259312
private void setupBenchmark(String benchmarkPath, JSONObject json) {
260313
SimpleDateFormat DATE_FORMAT_BENCHMARK = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
261314
String timestamp = DATE_FORMAT_BENCHMARK.format(System.currentTimeMillis());
@@ -294,6 +347,14 @@ private void setupBenchmark(String benchmarkPath, JSONObject json) {
294347
}
295348
}
296349

350+
/**
351+
* Downloads the smart contract bytecode from Etherscan based on the
352+
* benchmark path provided via the command line. The method retrieves the
353+
* smart contract file and saves it to the "download" directory.
354+
*
355+
* @param cmd The CommandLine object containing the options, specifically
356+
* the "benchmark" option that defines the path.
357+
*/
297358
private void downloadBytecode(CommandLine cmd) {
298359
SMARTCONTRACTS_FULLPATH = Paths.get(cmd.getOptionValue("benchmark")).toString();
299360
OUTPUT_DIR = Paths.get("download").toString();
@@ -304,6 +365,18 @@ private void downloadBytecode(CommandLine cmd) {
304365
}
305366
}
306367

368+
/**
369+
* Sets up the analysis directories based on the provided command line
370+
* options. If an "address" option is provided, it is used to create the
371+
* output directory. Otherwise, a default address is generated based on the
372+
* current timestamp. The method creates the necessary directories and sets
373+
* file paths for statistics and failure files.
374+
*
375+
* @param cmd The CommandLine object containing the options, specifically
376+
* the "address" option.
377+
*
378+
* @return The address used to set up the output directory.
379+
*/
307380
private String setupAnalysisDirectories(CommandLine cmd) {
308381
String address;
309382
if (!cmd.hasOption("address"))
@@ -327,6 +400,20 @@ private String setupAnalysisDirectories(CommandLine cmd) {
327400
return address;
328401
}
329402

403+
/**
404+
* Sets up the bytecode by either reading it from a file or fetching it from
405+
* Etherscan, depending on the command line options. If the
406+
* "mnemonic-bytecode" option is provided, it returns the path of the
407+
* mnemonic-bytecode directly. Otherwise, the bytecode is fetched either
408+
* from the specified bytecode file or from Etherscan, and the opcodes are
409+
* parsed from the bytecode and saved to a file.
410+
*
411+
* @param cmd The CommandLine object containing the options, specifically
412+
* the "mnemonic-bytecode", "filepath-bytecode", and
413+
* "address" options.
414+
*
415+
* @return The path to the bytecode file where the opcodes are stored.
416+
*/
330417
private String setupBytecode(CommandLine cmd) {
331418
if (cmd.hasOption("mnemonic-bytecode"))
332419
return cmd.getOptionValue("mnemonic-bytecode");
@@ -360,6 +447,20 @@ private String setupBytecode(CommandLine cmd) {
360447
return bytecodePath;
361448
}
362449

450+
/**
451+
* Creates and configures a LiSAConfiguration object based on the provided
452+
* command line options. This method initializes various properties of the
453+
* configuration, such as serialization options, analysis type, output
454+
* settings, and others based on the command line options.
455+
*
456+
* @param address The address of the smart contract to analyze, used for
457+
* setting up the abstract state.
458+
* @param cmd The CommandLine object containing the options for
459+
* configuring the analysis.
460+
*
461+
* @return A configured LiSAConfiguration object ready for use in the
462+
* analysis.
463+
*/
363464
private LiSAConfiguration createLiSAConfig(String address, CommandLine cmd) {
364465
LiSAConfiguration conf = new LiSAConfiguration();
365466
conf.serializeInputs = cmd.hasOption("serialize-inputs");
@@ -480,7 +581,7 @@ private MyLogger newAnalysis(String CONTRACT_ADDR, JSONObject jsonOptions) throw
480581
* soundly solved jumps after applying the iterative resolution
481582
* process
482583
*/
483-
Set<Statement> getSoundlySolvedJumps(JumpSolver checker, LiSA lisa, Program program) {
584+
public static Set<Statement> getSoundlySolvedJumps(JumpSolver checker, LiSA lisa, Program program) {
484585
HashSet<Statement> soundlySolved = new HashSet<>();
485586
if (JumpSolver.getLinkUnsoundJumpsToAllJumpdest()) {
486587
int currentIteration = 0;
@@ -1143,6 +1244,20 @@ private Options getOptions() {
11431244
.hasArg(false)
11441245
.build();
11451246

1247+
Option crossChainABIOption = Option.builder()
1248+
.longOpt("cross-chain-abi")
1249+
.desc("Path of the folder containing the ABIs of the cross chain smart contracts")
1250+
.required(false)
1251+
.hasArg(true)
1252+
.build();
1253+
1254+
Option crossChainBytecodeOption = Option.builder()
1255+
.longOpt("cross-chain-bytecode")
1256+
.desc("Path of the folder containing the bytecodes of the cross chain smart contracts")
1257+
.required(false)
1258+
.hasArg(true)
1259+
.build();
1260+
11461261
options.addOption(addressOption);
11471262
options.addOption(outputOption);
11481263
options.addOption(filePathOption);
@@ -1163,6 +1278,8 @@ private Options getOptions() {
11631278
options.addOption(dumpDotOption);
11641279
options.addOption(enableReentrancyCheckerOption);
11651280
options.addOption(enableTxOriginCheckerOption);
1281+
options.addOption(crossChainABIOption);
1282+
options.addOption(crossChainBytecodeOption);
11661283

11671284
return options;
11681285
}

0 commit comments

Comments
 (0)