Skip to content

Commit 06fd3d0

Browse files
committed
Refactored event order checker with the new custom policy mechanism
1 parent 20059c4 commit 06fd3d0

File tree

2 files changed

+44
-48
lines changed

2 files changed

+44
-48
lines changed

src/main/java/it/unipr/crosschain/xEVMLiSA.java

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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());

src/test/java/it/unipr/analysis/cron/SmartaxeBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ private void runBenchmark() {
116116
for (Bridge bridge : bridges)
117117
for (SmartContract contract : bridge) {
118118
futures.add(EVMLiSAExecutor.submit(SmartaxeBenchmark.class,
119-
() -> xEVMLiSA.runEventOrderChecker(bridge, contract)));
119+
() -> xEVMLiSA.runEventOrderChecker(contract, bridge.getPolicy())));
120120
futures.add(EVMLiSAExecutor.submit(SmartaxeBenchmark.class,
121121
() -> xEVMLiSA.runAccessControlIncompleteness(contract)));
122122
futures.add(EVMLiSAExecutor.submit(SmartaxeBenchmark.class,

0 commit comments

Comments
 (0)