Source-linked AI summary
Rethinking Smart Contract Fuzzing: Fuzzing With Invocation Ordering and Important Branch Revisiting
Zhenguang Liu, Peng Qian, Jiaxu Yang, Lingfeng Liu, Xiaojun Xu, Qinming He, Xiaosong Zhang
TL;DR
Existing smart-contract fuzzers can miss complex contract states and give equal attention to branches, including rare or vulnerable ones. IR-Fuzz combines dependency-aware invocation sequences, branch-distance seed evolution, and branch-aware energy allocation. Evaluated on 12K real-world contracts, it reports higher branch coverage and vulnerability-detection accuracy than current methods.
Problem
Existing fuzzers may overlook function dependencies and complex states, while equal branch treatment can leave rare or vulnerable branches underexplored.
Source: §III · p. 4Method
IR-Fuzz orders and prolongs function invocation sequences, evolves seeds using branch distance, and directs fuzzing energy toward rare or vulnerable branches.
Source: §I · p. 2Results
Up to 90% average branch coverage and 28% improvement over state-of-the-art fuzzers; average vulnerability-detection accuracy increases 7% over current methods.
Source: §I · p. 2Takeaways & Limitations
The authors provide a large benchmark dataset and release it with their implementation for smart-contract fuzzing research.
Source: §I · p. 2
Abstract
from arXiv · showhide
Blockchain smart contracts have given rise to a variety of interesting and compelling applications and emerged as a revolutionary force for the Internet. Quite a few practitioners have devoted themselves to developing tools for detecting bugs in smart contracts. One line of efforts revolve around static analysis techniques, which heavily suffer from high false-positive rates. Another line of works concentrate on fuzzing techniques. Unfortunately, current fuzzing approaches for smart contracts tend to conduct fuzzing starting from the initial state of the contract, which expends too much energy revolving around the initial state and thus is usually unable to unearth bugs triggered by other states. Moreover, most existing methods treat each branch equally, failing to take care of the branches that are rare or more likely to possess bugs. This might lead to resources wasted on normal branches. In this paper, we try to tackle these challenges from three aspects: (1) In generating function invocation sequences, we explicitly consider data dependencies between functions to facilitate exploring richer states. We further prolong a function invocation sequence S1 by appending a new sequence S2, so that S2 can start fuzzing from states that are different from the initial state. (2) We incorporate a branch distance-based measure to evolve test cases iteratively towards a target branch. (3) We engage a branch search algorithm to discover rare and vulnerable branches, and design an energy allocation mechanism to take care of exercising these crucial branches. We implement IR-Fuzz and extensively evaluate it over 12K real-world contracts. Empirical results show that: (i) IR-Fuzz achieves 28% higher branch coverage than state-of-the-art fuzzing approaches, and (ii) IR-Fuzz detects more vulnerabilities and increases the average accuracy of vulnerability detection by 7% over current methods.
I. INTRODUCTION
The introduction identifies limitations in existing smart-contract analysis and fuzzing, then presents IR-Fuzz’s sequence generation, seed optimization, and branch-aware energy allocation. Its evaluation reports higher branch coverage and vulnerability-detection accuracy than current methods.
I. INTRODUCTION
- Static analysis has high false-positive rates, while fuzzers overlook function dependencies, complex states, branch distance, and branch importance.These gaps can leave fuzzers circling initial states or spending resources on normal branches rather than rare or vulnerable ones.Source: §I · pp. 1–2
- IR-Fuzz orders function calls using global-variable data dependencies and prolongs sequences to explore states beyond the initial state.A data-flow analyzer identifies dependencies and assigns function-call order priorities.Source: §I · p. 2
- Branch-distance guidance selects and iteratively evolves test cases toward satisfying conditions of just-missed branches.Cases closer to satisfying a branch condition are more likely to enter that branch.Source: §I · p. 2
- A branch-search algorithm identifies rare and potentially vulnerable branches, and an energy schedule directs more fuzzing resources toward them.The paper reports IR-Fuzz is 4.9x faster than sFuzz.Source: §I · p. 2
- Up to 90% average branch coverage and 28% improvement over state-of-the-art fuzzers; average vulnerability-detection accuracy increases 7% over current methods.The evaluation covered 12K real-world smart contracts and reports an average of 350 test cases per second.Source: §I · p. 2
- The authors also construct a benchmark dataset for smart-contract fuzzing and release it with their implementation.The evaluation is described as large-scale and conducted on real-world smart contracts.Source: §I · p. 2
II. RELATED WORK
Prior smart-contract vulnerability detection spans formal and symbolic techniques as well as fuzzing, while greybox fuzzers pursue broad coverage or targeted locations. The GuessNum example illustrates how invocation order, difficult conditions, and branch prioritization affect vulnerability discovery.
A. Smart Contract Vulnerability Detection
- Formal verification and symbolic execution can provide guarantees or discover bugs, but cited approaches face semi-automation, false positives, or path explosion; fuzzers still struggle with coverage and efficiency.The section describes ContractFuzzer, ReGuard, Harvey, ILF, and sFuzz among prior fuzzing work.Source: A. Smart Contract Vulnerability… · pp. 2–3
B. Greybox Fuzzing
- Greybox fuzzing divides into coverage-guided approaches seeking broad path or branch coverage and targeted approaches steering tests toward selected locations.Examples include AFL for coverage and AFLGo for target-location guidance.Source: B. Greybox Fuzzing · p. 3
III. MOTIVATING EXAMPLE
- GuessNum’s getReward() is reentrant because an external transfer can invoke the recipient’s fallback before the user’s balance is reduced.The attacker can re-enter getReward() while the first transfer is pending and receive money again.Source: §III · p. 3
- The example exposes three fuzzing challenges: invocation order affects reachability, strict conditions are difficult to satisfy, and vulnerable branches may receive too few resources.The text notes that the vulnerable lines 18–20 occur in only one branch.Source: §III · pp. 3–4
- IR-Fuzz orders dependent calls, evolves seeds by branch distance, and allocates energy to rare or vulnerable branches; after 26 seconds, it reached the vulnerable branch and exposed reentrancy.For GuessNum, it orders guess() before getReward() and measures distance to the msg.value == 50 condition as |msg.value - 50|.Source: §III · p. 4
IV. METHOD
IR-Fuzz orders function calls using global-variable dependencies and prolongs those sequences to explore contract states beyond the initial state. It also allocates fuzzing energy toward rare or potentially vulnerable branches and checks generated logs for vulnerability patterns.
IV. METHOD
- IR-Fuzz generates ordered function invocation sequences and prolongs them to explore deeper contract states.The method overview also identifies energy allocation toward rare or likely vulnerable branches as a component.Source: §IV · p. 4
- Generated logs are checked against vulnerability-specific patterns, and bug reports are produced for manual inspection.Source: §IV · p. 4
A. Sequence Generation
- IR-Fuzz orders calls by analyzing global-variable read/write dependencies and assigning higher priority to functions that write variables read by other functions.Functions are sorted by their order-priority scores to form the invocation sequence.Source: A. Sequence Generation · p. 5
- Sequence prolongation appends a parameterized invocation sequence to an earlier run, letting the appended sequence start from a different contract state.The two sequences are selected with different inputs; for sequences with more than two required parameters, at least two must differ.Source: A. Sequence Generation · p. 6
- In the crowdfunding example, prolonging donate(300) → withdraw() with donate(200) → withdraw() reaches a later withdraw branch that exposes a potential Ether-frozen vulnerability.The first donation reaches the goal; the second sets the phase before the second withdrawal.Source: A. Sequence Generation · pp. 6–7
B. Seed Evolution
Seed evolution keeps tests that cover new branches and uses branch distance to select tests nearer to uncovered conditions. It mutates prioritized seeds and verifies generated cases.
B. Seed Evolution
- IR-Fuzz adds tests covering new branches to its suite, then iteratively evolves selected tests through mutation until the mutation-energy limit is reached.Tests are selected using branch-distance feedback and mutations are verified for validity.Source: B. Seed Evolution · p. 7
- For each just-missed branch, IR-Fuzz selects a test case with the smallest branch distance, a measure of how far it is from satisfying the branch condition.The distance rules cover equality, inequality, and ordered comparisons; x and k are extracted from recorded stack information.Source: B. Seed Evolution · p. 7
- Seeds with smaller branch distances receive preferential mutation, while invalid or duplicate generated cases are discarded.Validity checks include bit verification; seeds that fail to discover a new branch after a mutation round receive low priority.Source: B. Seed Evolution · p. 7
C. Energy Allocation
IR-Fuzz identifies rare and vulnerable branches, then allocates more fuzzing energy to them. Its allocation feedback also guides seed selection and mutation.
C. Energy Allocation
- Branch analysis identifies rare branches by nested conditionals and vulnerable branches by the presence of vulnerable statements.A rare branch has at least two nested conditionals; its rarity factor is the number of nested conditionals.Source: C. Energy Allocation · p. 8
- The authors report that over half of bugs are in rare and vulnerable branches, and use an abstract interpreter to identify those branches among discovered paths.The reported experimental proportions are 65% and 86%.Source: C. Energy Allocation · p. 8
- The energy schedule gives higher-rarity branches more energy and assigns vulnerable branches an α-weighted allocation when rarity factors match.For a vulnerable branch, the allocation is α∗E, with α > 1; higher rarity receives a larger ∇-weighted allocation.Source: C. Energy Allocation · p. 8
- IR-Fuzz reaches a vulnerable branch and exposes a block-number dependency in an average of 8 seconds, while sFuzz cannot reach that branch in the example.The reported time ranges from 4 to 12 seconds across five runs.Source: C. Energy Allocation · p. 8
- Energy-allocation feedback prioritizes test cases covering vulnerable branches for seed selection and mutation.The authors state that this mechanism can flexibly direct resources to rare and vulnerable branches, increasing overall fuzzing efficiency and branch coverage.Source: C. Energy Allocation · p. 8
D. Vulnerability Analysis and Report
IR-Fuzz uses vulnerability-specific patterns to analyze fuzzing results and generate reports for manual confirmation. Its reentrancy check combines evidence of a call.value invocation with evidence that the function was called repeatedly.
D. Vulnerability Analysis and Report
- IR-Fuzz's pattern analyzer handles eight vulnerability types, including timestamp and block-number dependencies, dangerous delegatecall, reentrancy, and integer overflow.It analyzes fuzzing results and produces a detailed bug report for manual confirmation.Source: D. Vulnerability Analysis and Report · pp. 8–9
- The reentrancy pattern requires both a call.value invocation and repeated calls to the function containing it during fuzzing.The paper describes reentrancy as call.value being re-entered through a call chain to perform unexpected repeat money transfers.Source: D. Vulnerability Analysis and Report · p. 9
- IR-Fuzz reports reentrancy when the combined CALLValueInvocation and RepeatedCallValue patterns are satisfied.Source: D. Vulnerability Analysis and Report · p. 9
E. IR-Fuzz Workflow Illustration with an Example
The example traces IR-Fuzz from contract source through dependency-guided fuzzing to log-based vulnerability analysis. The workflow uses the inferred invocation sequence and later extends it to explore more complex states.
E. IR-Fuzz Workflow Illustration with an Example
- IR-Fuzz compiles the contract source into a JSON file containing EVM bytecode and the application binary interface.Source: E. IR-Fuzz Workflow Illustration with… · p. 9
- It extracts global-variable data dependencies from the syntax tree to infer the invocation sequence guess() → getReward().Source: E. IR-Fuzz Workflow Illustration with… · p. 9
- IR-Fuzz generates test cases for the ordered calls, keeps high-quality cases using branch distance, and uses branch analysis and energy allocation to guide seed selection and mutation.Source: E. IR-Fuzz Workflow Illustration with… · p. 9
- After fuzzing reaches the transfer branch, an attack-contract generator simulates a reentrant call to getReward(), and log analysis checks whether call.value ran multiple times.IR-Fuzz uses vulnerability-specific patterns to expose the reentrancy vulnerability.Source: E. IR-Fuzz Workflow Illustration with… · p. 9
- IR-Fuzz prolongs the ordered invocation sequence to explore other complex states.Source: E. IR-Fuzz Workflow Illustration with… · p. 9
V. EXPERIMENTS
The experiments are organized around vulnerability detection, branch coverage, fuzzing efficiency, and component contributions. The paper also presents a case study to illustrate the approach.
V. EXPERIMENTS
- RQ1 asks whether IR-Fuzz detects contract vulnerabilities effectively and how it compares with state-of-the-art tools.Source: §V · p. 9
- RQ2 asks whether IR-Fuzz achieves higher branch coverage than existing methods.Source: §V · p. 9
- RQ3 asks how efficiently IR-Fuzz fuzzes contracts and generates test cases compared with other fuzzers.Source: §V · p. 9
- RQ4 examines how IR-Fuzz components contribute to branch coverage and vulnerability-detection accuracy; the experiments also include a case study.Source: §V · p. 9
A. Experimental Setup
IR-Fuzz was implemented on sFuzz and evaluated against fuzzers and static-analysis tools using verified Ethereum contracts labeled for eight vulnerability types.
A. Experimental Setup
- IR-Fuzz is implemented in 9K+ lines of C++ on the sFuzz codebase and was released for public use.The implementation is described as based on a state-of-the-art smart contract fuzzer.Source: A. Experimental Setup · p. 9
- The benchmark covers eight vulnerability categories, including dangerous Ether strict equality (SE), alongside the supported vulnerability types of state-of-the-art methods.The categories are timestamp dependency, block number dependency, dangerous delegatecall, Ether frozen, unchecked external call, reentrancy, integer overflow, and SE.Source: Table I · p. 10, A. Experimental Setup · p. 10
- The comparison includes three fuzzers and four static-analysis tools, with experiments repeated ten times and average results reported.Fuzzers: ConFuzzius, ILF, and sFuzz; static-analysis tools: Mythril, Oyente, Osiris, and Securify. Experiments used an Intel Core i9 CPU, a 2080Ti GPU, and 64GB memory.Source: A. Experimental Setup · p. 10
- The evaluation uses 12,515 verified Ethereum contracts after removing 5,074 duplicates, with labels for eight vulnerability types.Contracts were deployed to a local Ethereum test network; vulnerability-specific patterns provided preliminary labels that were manually checked.Source: A. Experimental Setup · p. 10
B. Effectiveness (RQ1)
IR-Fuzz reports higher vulnerability-detection accuracy than competing methods across the evaluated vulnerability types, and identifies dangerous Ether strict equality that current automatic tools do not detect. The evaluation also examines true and false positives, where existing methods show substantial false positives.
B. Effectiveness (RQ1)
- IR-Fuzz achieves more than 90% accuracy on all eight vulnerability types and reports 15.63% and 16.14% accuracy improvements for Ether frozen over Securify and ConFuzzius, respectively.The accuracy comparison covers static-analysis tools, fuzzers, and IR-Fuzz; ‘n/a’ indicates that a tool cannot detect a specific vulnerability.Source: B. Effectiveness (RQ1) · p. 10, Table II · p. 10
- IR-Fuzz consistently outperforms state-of-the-art methods in detecting each vulnerability type, and the authors attribute its performance to sequence generation, seed optimization, and energy allocation.The paper reports that current automatic tools cannot detect dangerous Ether strict equality.Source: B. Effectiveness (RQ1) · p. 10
- Existing methods show high false positives: sFuzz, ConFuzzius, and ILF each report over 100 for block number dependency, while Osiris, Oyente, and ConFuzzius report 632, 637, and 565 for integer overflow.The authors attribute these results to imprecise patterns and conservative assumptions about arithmetic operations.Source: B. Effectiveness (RQ1) · pp. 10–11, Table III · p. 10
- IR-Fuzz finds vulnerabilities in 485 contracts, roughly 4.7 times more than sFuzz, and detects dangerous Ether strict equality without false positives.For timestamp dependency, it produces 92 true positives—88, 80, and 69 more than Osiris, Oyente, and sFuzz, respectively.Source: B. Effectiveness (RQ1) · p. 11
C. Branch Coverage (RQ2)
IR-Fuzz reports higher branch coverage than other fuzzers on small and large contracts, and reaches the highest coverage in less time. Its efficiency evaluation also compares the full method with variants that remove each of its three components.
C. Branch Coverage (RQ2)
- 90.10% branch coverage on small contracts is 28.20%, 20.10%, and 10.10% higher than sFuzz, ILF, and ConFuzzius, respectively.On large contracts, IR-Fuzz achieves 19.20%, 14.00%, and 9.10% higher coverage than those fuzzers, respectively; Fig. 6 plots coverage over time for both contract sizes.Source: C. Branch Coverage (RQ2) · p. 11
D. Efficiency (RQ3)
- IR-Fuzz spends 21.30s per contract on average, 251s faster than Securify and 82.22s faster than sFuzz.It spends an average of 10s to reach its highest coverage, compared with 18s, 16s, and 13s for the other three fuzzers.Source: D. Efficiency (RQ3) · p. 11, C. Branch Coverage (RQ2) · p. 11, Figure 7 · p. 11
- Without sequence generation, IR-Fuzz’s reentrancy-task accuracy and branch coverage are lower by 3.97% and 23.62%, respectively.The variant replaces the strategy with random sequence construction.Source: E. Ablation Study (RQ4) · p. 12, Table IV · p. 12
- Without branch-distance-based seed evolution, accuracy and branch coverage are lower by averages of 2.03% and 15.76% across the eight vulnerability types.The variant uses random test-case generation.Source: E. Ablation Study (RQ4) · p. 12, Table IV · p. 12
- Without energy allocation, accuracy and branch coverage are lower by averages of 4.87% and 43.02% across the eight vulnerability types.The variant assigns fuzzing energy equally to every branch.Source: E. Ablation Study (RQ4) · p. 12, Table IV · p. 12
F. Case Study
IR-Fuzz detects a dangerous Ether strict equality vulnerability that existing tools missed. The discussion identifies seed-mutation and sequence-ordering costs, while the conclusion summarizes the framework’s approach.
F. Case Study
- Pre-stored Ether can make the contract balance unequal to users’ participation fees, leaving no winner and permanently freezing those fees.The equality condition is checked at line 14; the winner would otherwise claim the contract balance by calling newGame().Source: F. Case Study · p. 12
- IR-Fuzz identified dangerous Ether strict equality in a gambling contract that existing tools did not detect.It inferred the sequence guess()→newGame(), reached the relevant code, and triggered vulnerability-specific patterns.Source: F. Case Study · p. 12
- At line 14, IR-Fuzz records BALANCE and checks for a following jump or compare instruction before reporting the vulnerability pattern.The case study’s sequence is guess()→newGame().Source: F. Case Study · pp. 12–13
VI. DISCUSSION
- Analyzing global-variable data dependencies to prioritize function calls may add computation overhead when functions frequently read and write those variables.Source: §VI · p. 13
- AFL-derived bit mutations can generate repetitive, invalid tests and alter critical input parts, reducing the chance of reaching branches with strict conditions.The authors propose avoiding mutation of crucial test-case parts as future work.Source: §VI · p. 13
VII. CONCLUSION
- IR-Fuzz combines invocation ordering and sequence prolongation, branch-distance-guided seed evolution, and energy allocation toward rare and vulnerable branches.The conclusion reports improved fuzzing efficiency and branch coverage, and says the techniques might transfer to other software.Source: §VII · p. 13