@@ -263,7 +263,7 @@ public static void runCrossChainCheckers(Bridge bridge) {
263263 List <Future <?>> futures = new ArrayList <>();
264264 for (SmartContract contract : bridge ) {
265265 futures .add (
266- EVMLiSAExecutor .submit (xEVMLiSA .class , () -> runEventOrderChecker (bridge , contract )));
266+ EVMLiSAExecutor .submit (xEVMLiSA .class , () -> runEventOrderChecker (contract , bridge . getPolicy () )));
267267 futures .add (
268268 EVMLiSAExecutor .submit (xEVMLiSA .class ,
269269 () -> runMissingEventNotificationChecker (contract , bridge .getPolicy ())));
@@ -354,15 +354,14 @@ public static void runAccessControlIncompleteness(SmartContract contract) {
354354 /**
355355 * Executes the Event Order Checker on a single contract. For each public
356356 * function: (i) Follow only successful return paths (STOP for void, RETURN
357- * otherwise). (ii) Collect any SSTORE and LOG instructions on that path.
358- * (iii) If LOGs occur without a preceding SSTORE, flag an event-order
359- * issue. (iv) Classify as definite if across a cross‑chain edge, else
360- * possible.
357+ * otherwise). (ii) Collect any SSTORE and events emission instructions on
358+ * that path. (iii) If events occur without a preceding SSTORE, flag an
359+ * event-order warning.
361360 *
362- * @param bridge the Bridge providing the cross-chain CFG context
363361 * @param contract the specific SmartContract to analyze
362+ * @param policy the CustomPolicy used for cross-chain links
364363 */
365- public static void runEventOrderChecker (Bridge bridge , SmartContract contract ) {
364+ public static void runEventOrderChecker (SmartContract contract , CustomPolicy policy ) {
366365 log .info ("[IN] Running event order checker on {}." , contract .getName ());
367366
368367 EVMCFG cfg = contract .getCFG ();
@@ -396,55 +395,51 @@ public static void runEventOrderChecker(Bridge bridge, SmartContract contract) {
396395 && exitpoint instanceof Return )
397396 continue ;
398397
399- /* We take only the state updates inside the function */
400- Set <Statement > sstores = cfg .getStatementsInAPathWithTypes (entrypoint , exitpoint ,
401- Set .of (Sstore .class ));
402- /* We take only the log instructions inside the function */
403- Set <Statement > logs = cfg .getStatementsInAPathWithTypes (entrypoint , exitpoint ,
404- Set .of (Log1 .class , Log2 .class , Log3 .class , Log4 .class ));
405-
406- /*
407- * If there is no state update but at least a LOG
408- * instruction, a (possible) warning is raised
409- */
410- if (sstores .isEmpty () && !logs .isEmpty ()) {
411- for (Statement emitEvent : logs ) {
412- ProgramCounterLocation entrypointLocation = (ProgramCounterLocation ) entrypoint
413- .getLocation ();
414- ProgramCounterLocation emitEventLocation = (ProgramCounterLocation ) emitEvent .getLocation ();
398+ Set <String > eventsPolicy = policy .getEventsForFunction (function .getName ());
399+ Set <Signature > eventsContract = contract .getEventsSignature ();
400+ Set <Statement > eventsExitpoints = new HashSet <>();
415401
416- if (bridge .getXCFG ().hasAtLeastOneCrossChainEdge (emitEvent )) {
417- String warn = "[DEFINITE] Event Order vulnerability at " + emitEventLocation .getPc ();
402+ for (String eventPolicy : eventsPolicy ) {
403+ for (Signature eventContract : eventsContract ) {
404+ if (!eventPolicy .equalsIgnoreCase (eventContract .getName ()))
405+ continue ;
406+ eventsExitpoints .addAll (eventContract .getExitPoints ());
407+ }
408+ }
418409
419- log .warn (
420- "[DEFINITE] Event Order vulnerability at pc {} (line {}) coming from pc {} (line {})." ,
421- emitEventLocation .getPc (),
422- emitEventLocation .getSourceCodeLine (),
423- entrypointLocation .getPc (),
424- entrypointLocation .getSourceCodeLine ());
410+ /* Skip if we have no event exitpoints */
411+ if (eventsExitpoints .isEmpty ())
412+ continue ;
425413
426- MyCache .getInstance ().addEventOrderWarning (cfg .hashCode (), warn );
414+ /* We take only state updates inside the function */
415+ Set <Statement > sstores = cfg .getStatementsInAPathWithTypes (entrypoint , exitpoint , Sstore .class );
427416
428- warn = "[DEFINITE] Event Order vulnerability in " + contract .getName () + " at "
429- + function .getFullSignature ()
430- + " (pc: " + emitEventLocation .getPc () + ", "
431- + "line: " + emitEventLocation .getSourceCodeLine () + ")" ;
432- MyCache .getInstance ().addVulnerabilityPerFunction (cfg .hashCode (), warn );
417+ for (Statement emitEvent : eventsExitpoints ) {
418+ if (cfg .reachableFromWithoutStatements (entrypoint , emitEvent , sstores )) {
433419
434- } else {
435- String warn = "[POSSIBLE] Event Order vulnerability at " + emitEventLocation .getPc ();
420+ ProgramCounterLocation entrypointLocation = (ProgramCounterLocation ) entrypoint
421+ .getLocation ();
422+ ProgramCounterLocation emitEventLocation = (ProgramCounterLocation ) emitEvent .getLocation ();
436423
437- log .warn (
438- "[POSSIBLE] Event Order vulnerability at pc {} (line {}) coming from pc {} (line {})." ,
439- emitEventLocation .getPc (),
440- emitEventLocation .getSourceCodeLine (),
441- entrypointLocation .getPc (),
442- entrypointLocation .getSourceCodeLine ());
424+ String warn = "Event Order warning at " + emitEventLocation .getPc ();
443425
444- MyCache .getInstance ().addPossibleEventOrderWarning (cfg .hashCode (), warn );
445- }
426+ log .warn (
427+ "Event Order warning at pc {} (line {}) coming from pc {} (line {})." ,
428+ emitEventLocation .getPc (),
429+ emitEventLocation .getSourceCodeLine (),
430+ entrypointLocation .getPc (),
431+ entrypointLocation .getSourceCodeLine ());
432+
433+ MyCache .getInstance ().addEventOrderWarning (cfg .hashCode (), warn );
434+
435+ warn = "Event Order warning in " + contract .getName () + " at "
436+ + function .getFullSignature ()
437+ + " (pc: " + emitEventLocation .getPc () + ", "
438+ + "line: " + emitEventLocation .getSourceCodeLine () + ")" ;
439+ MyCache .getInstance ().addVulnerabilityPerFunction (cfg .hashCode (), warn );
446440 }
447441 }
442+
448443 }
449444 }
450445 }
@@ -464,6 +459,7 @@ public static void runEventOrderChecker(Bridge bridge, SmartContract contract) {
464459 * missing notifications as vulnerabilities.
465460 *
466461 * @param contract the SmartContract to analyze for missing event logs
462+ * @param policy the CustomPolicy used for cross-chain links
467463 */
468464 public static void runMissingEventNotificationChecker (SmartContract contract , CustomPolicy policy ) {
469465 log .info ("[IN] Running missing event notification checker on {}." , contract .getName ());
0 commit comments