66import it .unipr .checker .JumpSolver ;
77import it .unipr .checker .ReentrancyChecker ;
88import it .unipr .checker .TxOriginChecker ;
9+ import it .unipr .crossChainAnalysis .BridgeAnalysis ;
910import it .unipr .frontend .EVMFrontend ;
1011import it .unive .lisa .LiSA ;
1112import 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