1. Introduction
Blockchain technology was first described by Satoshi Nakamoto in his published article in 2008. Blockchain is a kind of distributed shared ledger [
1], which saves the information of Bitcoin transactions in individual blocks by means of distributed storage, and the data of each block determine the generation of its sub-blocks. However, Bitcoin is relatively single-function and cannot realize complex applications on the blockchain network, which limits its practical application value. In the development of blockchain technology, the emergence of Ethereum has solved this problem well, making the commercial application of blockchain possible.
Ethereum [
2] is a decentralized application platform that, similar to cryptocurrencies such as Bitcoin, has electronic payment and digital asset transfer capabilities. In addition, any user can build decentralized applications (DApps) [
3] on Ethereum to interact with other applications. These decentralized applications are composed of smart contracts, which manage many of the key features, operations, and user behaviors of Ether. The concept of smart contracts [
4,
5] was first introduced by cryptographer Szabo as computerized transaction protocols stored digitally that automatically enforce the terms of a contract.
In recent years, with the growing maturity of smart contract technology and its wide application on blockchain platforms, more and more scholars have noticed that vulnerabilities in smart contracts pose a significant threat to the security of users and blockchain platforms [
6]. For example, DAO, the world’s largest crowdfunding project deployed on Ether, was hacked, resulting in the loss of more than ETH 3 million from the DAO pool [
7], and Parity, an Ether multi-signature wallet, also suffered from a security vulnerability, resulting in the theft of more than ETH 150,000 (about USD 30 million) [
8], and the painful lessons of such incidents highlight the importance of ensuring the security and correctness of smart contracts.
The current blockchain ecosystem is highly heterogeneous, with various platforms using distinct smart contract programming languages such as Solidity for Ethereum, C++ for EOS, and Go for Hyperledger. While this diversity has enabled unique functionalities, it has also led to significant standardization issues. Different languages and technical architectures result in poor cross-platform code compatibility, complicating migration and validation. Moreover, this diversity impacts the consistency of development tools and frameworks, posing challenges for establishing unified security auditing standards. Each language has its own vulnerabilities and risks, making standardized security measures difficult to implement across platforms. For instance, recursive attacks can exhaust contract resources, excessive privileges can lead to malicious manipulation, and issues with randomness can introduce uncertainty and increase manipulation risks. Detailed attack types are listed in
Appendix A.
Traditional security auditing methods, which rely on manual reviews and testing, are inefficient and prone to overlooking unforeseen logic errors and vulnerabilities. To address these challenges, this paper integrates an input module, static analysis module, formal verification module, simulation execution module, and a report and recommendation module, making the following contributions:
Capable of accurately identifying issues such as security vulnerabilities and logic flaws in smart contracts through formalized verification and other technologies before smart contracts are deployed, thereby significantly improving the security of smart contracts and reducing the economic losses that may be caused by code defects.
Proposes a scalable, automated smart contract review methodology that minimizes reliance on manual review and ensures comprehensive and consistent assessment of smart contracts, thereby improving the overall security and reliability of blockchain applications.
Simplifies the review process, shortens the development cycle, and generates clear and actionable audit reports, thereby improving audit efficiency and reducing human security risks.
The rest of this paper is organized as follows.
Section 2 gives a presentation of the related proposals carried out in the area of smart contract formal verification. We propose a security audit method to discover the vulnerabilities of current smart contracts and make timely modifications before deploying smart contracts in
Section 3.
Section 4 detects all smart contracts deployed on the test network against various vulnerabilities.
Section 5 analyzes the advantages and disadvantages of the proposed approach. Finally, the conclusions and future work are discussed in
Section 6.
3. Security Audit Method
To enhance the security of smart contracts, this paper introduces a security audit approach that integrates formalization and model-checking techniques with formal verification. The method employs unified specifications to audit smart contract code, enabling users to systematically identify and mitigate vulnerabilities before deployment. By formalizing contract behavior and leveraging model checking to explore all potential states, this approach improves the precision of vulnerability detection, allowing for timely modifications and reducing the risk of security flaws in deployed contracts.
The main method proposed in this paper is illustrated in
Figure 1, consisting of five modules: an input module, a static analysis module, a formal verification module, a simulation execution module, and a report and recommendation module.
The input module receives and parses the smart contract source code, while the static analysis module uses the ACL2 [
34] tool to detect potential issues in the code. The formal verification module ensures the security of the contract through formal methods, and the simulation execution module evaluates the contract’s performance in different environments. Finally, the report and recommendation module synthesizes the results from all modules to generate an audit report and provide targeted improvement suggestions.
3.1. Input Module
This module is designed to receive and parse smart contract source code for formal verification and model testing. It processes contracts written in Solidity, identifying key functions and variables while ensuring the integrity of the original code’s semantics during conversion. By preprocessing and normalizing the input, this module enhances the accuracy and efficiency of subsequent reviews.
For instance, consider a smart contract implementing an online store. The store owner can add new products, update existing inventory, and withdraw ETH from the store’s balance. Users can view product details and make purchases. The ETH paid by users is adjusted according to the product price and quantity, The excess will be refunded to the user. Upon successful purchase, the item’s inventory is reduced, and all transactions and inventory changes are logged on-chain through events.
Figure 2 shows an example of the code of a smart contract.
With the smart contract code in
Figure 2, we can find the source code at
https://etherscan.io/address/0x27054b13b1b798b345b591a4d22e6562d47ea75a (accessed on 16 October 2024), the contract owner can add items, set the name, price, and inventory, and update the inventory; the user can purchase items by paying Ether, with the system checking the inventory and processing the payment. Any excess payment will be returned to the user. The contract owner can withdraw funds from the store, and the contract also provides functionality for querying item information. Events notify the contract of actions such as adding items, purchasing items, increasing inventory, and withdrawing funds. Importantly, each role within the contract is verified through specific functions to ensure that only authorized users can perform certain actions. Role validation mechanisms are integrated into the contract to check permissions before executing sensitive operations, such as modifying inventory or withdrawing funds. This ensures that all actions comply with the contract’s role-based access control. Some of the functions in
Figure 2 are explained as follows:
addItem(): Allows store owners to add new item information, including item name, price, and initial inventory, and assign a unique ID to the item. TheaddItem event is triggered after recording the item ID, name, price, and inventory information.
getItem(): Users can purchase a specified number of items and pay the corresponding ETH, and the system checks whether the item exists, whether there is enough inventory, and whether the Ether paid is enough. After successful purchase, the inventory will be reduced and the ItemPurchased event will be triggered to record the purchase information. If the paid Ether exceeds the total price, the excess will be refunded to the user.
purchaseItem(): Allows store owners to add inventory to existing items. The system checks if the item exists and adds the stock quantity. When the stock is successfully added, the StockAdded event is triggered, logging the item ID and the amount of stock added.
addStock(): The store owner can withdraw all the Ether accumulated in the contract. After calling this function, the ETH balance in the contract will be transferred to the owner’s address, and the FundsWithdrawn event will be triggered when the withdrawal is successful, recording the owner’s address and the amount withdrawn.
withdraw(): Allows any user to query the details of a specific item, including item name, price, and current stock. This information can be retrieved by item ID and returned to inform the user of the item's status.
The smart contracts received by this module are written in Solidity, and after being received and converted by the input unit, the next unit can receive the appropriate statements.
3.2. Static Analysis Module
The static analysis module is designed to detect potential issues early in the smart contract development process, ensuring security and reliability. By utilizing the ACL2 tool, this module automatically detects syntax and semantic errors, as well as potential security vulnerabilities, addressing them before they become significant failures or risks. This automated approach reduces the manual review workload while enhancing both detection efficiency and thoroughness. Moreover, it identifies and resolves issues affecting smart contract performance and gas consumption, thereby optimizing execution efficiency.
The module consists of several integrated components. First, the syntax-checking unit scans the source code of the smart contract and constructs an abstract syntax tree (AST). This process ensures that the code adheres to Solidity language specifications. Key parameters such as Solidity versioning, code consistency, security rule configuration, and compiler settings are employed to automatically detect and correct issues during the early stages of development, thereby improving both security and reliability.
Next, the semantic analysis unit traverses the AST using a depth-first search algorithm to detect semantic errors, such as variable type mismatches, improper handling of function return values, and logical inconsistencies. The code is first broken down into tokens—keywords, variable names, and operators—through lexical analysis and then organized into an internal structure according to Solidity’s syntax rules. As the AST is traversed, the semantic analyzer evaluates each node to verify type consistency and logical correctness, ensuring that the source code remains semantically sound.
The security rule unit applies predefined security rules to detect vulnerabilities in the code. It consists of two subcomponents: the security rule base, which contains detection rules for common vulnerabilities like reentrancy attacks and integer overflows, and the security audit subunit, which applies these rules to the code. During the security scan, the tool analyzes key elements like function calls and state variable modifications, using pattern recognition algorithms to identify potential security risks.
Finally, the result output unit generates a comprehensive report detailing syntax and semantic errors, as well as potential security vulnerabilities. Each issue is documented with its location, type, impact, and remediation recommendations. While automated tools catch many problems, a manual review is often necessary to confirm the validity of warnings and ensure that all issues have been accurately resolved. After corrections, the contract undergoes re-auditing to confirm that vulnerabilities have been eliminated and no new issues have been introduced.
An example of a static analysis algorithm transforms a program’s instruction sequence into a chain of blocks and a jump graph. The instructions are organized into blocks, and “JUMPI” instructions are processed to establish jump relationships, resulting in a jump graph that visually represents the control flow between blocks. This ensures that the structure of the contract is clear and can be verified for correctness.
Algorithm 1 constructs a program’s control flow graph by dividing the instruction sequence into basic blocks and establishing relationships between these blocks using jump instructions. Through this process, the static analysis tool organizes the program’s execution logic into distinct blocks and defines the jump paths, resulting in a clear control flow structure. This approach accurately represents the program’s execution path, helping developers understand the sequence of instructions and their branching behavior.
Algorithm 1 Building jump graphs |
Input: Program P Output: Blocks B and edges E
- 1:
B ← []
| |
|
// List of blocks |
- 2:
currentBlock ← null
| // Current block |
- 3:
E ←∅ - 4:
for each instruction S in P do - 5:
if S is the first instruction then - 6:
newBlock ← CreateNewBlock() - 7:
B.append(newBlock) - 8:
currentBlock ← newBlock - 9:
InsertIntoBlock(currentBlock,S) - 10:
end if - 11:
if S is “JUMPI” then - 12:
InsertIntoBlock(currentBlock,S) - 13:
EndBlock(currentBlock) - 14:
E[currentBlock] ←∅ - 15:
targetBlock← DetermineTargetBlock(S) - 16:
E[currentBlock].append(targetBlock) - 17:
newBlock ← CreateNewBlock() - 18:
B.append(newBlock) - 19:
currentBlock ← newBlock - 20:
end if - 21:
InsertIntoBlock(currentBlock,S) - 22:
end for - 23:
for each block in B do - 24:
if block ∈ E then - 25:
for each target in E[block] do - 26:
AddEdge(block,target) - 27:
end for - 28:
end if - 29:
end for
| // Edges between blocks |
In the review process, Algorithm 1 is employed to detect control flow issues by analyzing the jump relationships between blocks. It effectively identifies unreachable code, validates the safety of conditional jumps, and flags potential loops or recursive behavior, which contributes to robust control flow validation.
Proper parameter configuration is crucial for automating the detection and correction of issues in smart contract source code, enhancing both security and reliability. The Solidity code is scanned by a syntax analyzer to ensure compliance with language specifications, with parameters tailored to the specific Solidity version for compatibility. Code style settings are enforced for consistency and readability, while permitted and prohibited features are defined to avoid common vulnerabilities. Security rules are configured to prevent risky operations and unauthorized access, while compiler warnings and errors are adjusted to detect issues such as unused variables or unsafe functions. Additionally, code structure parameters ensure better organization, and optimization settings are configured to improve execution efficiency and reduce gas consumption, ultimately making the smart contract more secure and efficient.
3.3. Formal Verification Module
The tool configuration unit is responsible for selecting and configuring the appropriate formal verification tools. The parameter configuration unit sets verification parameters such as search depth, search width, and the security properties to be validated. The model construction unit builds the formal model of the smart contract based on its source code and the selected verification tool. Lastly, the verification analysis unit utilizes the configured tools to analyze the formal model against the predefined security attributes and produces the formal verification results.
Formal verification tools include the theorem prover Coq [
35], which constructs mathematical proofs to verify system correctness, and the model checker Spin, which systematically explores all possible states to validate system properties. Additionally, an algorithm library supports logical inference, state space exploration, and abstract interpretation to derive logical formulas, traverse system states, and approximate program behavior.
Selecting the appropriate formalization tools and algorithm libraries is critical to the success of the verification process. This selection depends on project needs, security and reliability requirements, tool maturity, ease of integration, and cost-effectiveness. For instance, Spin, along with the Promela language and linear temporal logic (LTL), is well-suited for smart contract systems with finite states, allowing the detection of security vulnerabilities through randomized state path generation.
During the verification process, the search depth controls how many state variables the tool considers, with greater depth uncovering more issues but requiring increased computational resources. Search width limits the number of state variables explored at each step, affecting search breadth and parallelism. Together, these parameters determine the scope and granularity of the verification.
The security attributes to be validated are clearly defined based on actual requirements and converted into formal specifications. As verification progresses, the auditor may need to adjust the formal model or verification parameters to refine the process. Once all security attributes are satisfied, the developer addresses the issues identified in the formal verification results. After the smart contract is repaired and optimized, the code is re-verified to ensure that previous vulnerabilities are resolved and no new issues are introduced.
The formal verification process is considered complete only when the smart contract successfully passes all verifications and fully meets the security attributes. This iterative approach ensures that the smart contract is secure and reliable for real-world deployment. Examples of Promela modeling code and properties to be verified are shown in
Figure 3.
The property verified by p1 is the invariance of the total account balance. Specifically, the total balance of each account in the smart contract should remain constant throughout the entire transaction process. In other words, the combined balance of all accounts should not change during any transactions or operations. Below are explanations for the functions involved in verifying this property:
Fa_stm(): Represents the production process with re_truck_id, truck_id, payment, and nb_goods variables, where nb_goods is initialized to 1000, and this process calls R_fa() in a loop to simulate the operation of production.
SCa_stm(): represents the smart contract A process with the payment variable, and R_sca() is called in a loop to simulate the behavior of smart contract A.
SCb_stm(): represents the smart contract B process with a fare variable, calling R_scb() in a loop to simulate the behavior of smart contract B.
Su_stm(): represents the supplier process with re_truck_id, payment, fare, and nb_goods variables, and R_su() is called in a loop to simulate the actions of the supplier.
Tr_stm(): represents a transport process with fare and id variables, where id is initialized to 1, and R_tr() is called in a loop to simulate transport operations.
To conduct model checking on a Promela model using the Spin tool 6.5.1, begin by generating the model checker and compiling the resulting c source files in the terminal or command line interface. Subsequently, execute the model checker to carry out the verification process. Upon completion, Spin will produce detailed model-checking results and a verification report, which are essential for assessing whether the system adheres to the specified properties and requirements across all possible execution scenarios. This procedure ensures a rigorous validation of the system’s behavior. The figure below shows the verification results of the Promela model using Spin.
Figure 4 illustrates the application of Spin, demonstrating a thorough and precise analysis with no errors found.. The tool comprehensively explored 2,269,701 state transitions and identified 1,510,039 distinct states, storing 759,662 of these as unique states. The state vector size was 272 bytes, and the search depth reached 9999 steps. Memory utilization was efficiently managed, with a total consumption of 262.226 MB, including 217.341 MB for state storage and 128 MB allocated for the hash table. The state storage compression efficiency reaches 61.60%, highlighting the tool's effective management of state storage. and indicates a robust verification process with optimal resource usage.
3.4. Analog Execution Module
The main objective of this module is to evaluate the performance of smart contracts in different operating environments through exhaustive simulations and in-depth analysis to ensure their security and robustness. The module consists of five core units: a state machine model building unit, state space graph construction unit, anomaly detection unit, simulation unit, and evaluation unit.
The
Figure 5 show the workflow of this module starts with constructing a state machine model derived from the source code of the smart contract, encompassing all possible states and their transitions. The state machine model building unit is responsible for creating this model, systematically detailing the various states of the smart contract and the relationships between them. This model not only offers a comprehensive view of the smart contract’s states but also facilitates a deeper understanding of its behavior under different operations and events.
The state space graph construction unit is based on the state machine model, and from which the state space graph is developed. The state space graph comprehensively covers all the state changes that a smart contract may experience during its life cycle, providing a basis for subsequent anomaly detection and simulation. Through this graphical representation, the state flow and potential paths of smart contracts can be understood intuitively. The anomaly detection unit is responsible for traversing the state space graph, detecting and recording potential risk paths that may exist during state transitions. The task of the anomaly detection unit is to identify potential anomalies and risky paths in the smart contract that may lead to unexpected behaviors or system vulnerabilities, thus providing critical information for further security analysis. The simulation unit employs advanced techniques to simulate smart contract operations in real-world scenarios. It generates various transactions, including normal, boundary conditions and intentionally malicious ones, to test how the smart contract handles different inputs. The unit also simulates blockchain event triggers, such as reaching specific time thresholds or account balance changes, to verify the correctness of the smart contract’s response logic. Additionally, it introduces abnormal conditions like transaction failures, network delays, and resource constraints to assess the smart contract’s performance under such scenarios.
The evaluation unit integrates results from the anomaly detection and simulation units to provide a comprehensive assessment of the smart contract. It analyzes the contract’s performance under normal and extreme conditions, focusing on stability and performance metrics such as execution efficiency, resource consumption, and response time. The unit also evaluates the contract’s security, identifying potential vulnerabilities and attack surfaces. Simulated execution results detail the execution paths of potential risks, successful and failed transactions, and reasons for any anomalies.
The simulation execution unit plays a key role in the vulnerability detection process of smart contracts, spanning the entire workflow from source code analysis to performance and security assessment. First, a state machine model is constructed based on the smart contract’s source code, and a state space graph is generated, covering all possible state changes throughout the contract’s life cycle, providing a foundation for subsequent anomaly detection and simulation. The anomaly detection module traverses the state space graph to identify potential risky execution paths, uncovering abnormal behaviors and unsafe operation patterns that may lead to vulnerabilities, such as reentrancy attacks and timestamp manipulation. Building on this, the simulation unit employs advanced simulation techniques to emulate various scenarios in a real blockchain environment, including normal transactions, malicious attacks, and boundary conditions, to assess the contract’s performance under different inputs and extreme conditions. Finally, the evaluation unit integrates the results from the simulation execution to comprehensively evaluate the smart contract’s performance and security, ensuring stability and reliability before formal deployment. This process effectively reduces the security risks associated with the contract after it goes live.
Through this detailed and comprehensive simulation execution process, the simulated execution module provides developers with a powerful tool to help identify and fix potential problems before the smart contract is formally deployed. This pre-assessment and optimization can significantly improve the reliability and security of smart contracts, ensuring that they can stably and reliably perform their intended functions in actual operation.
3.5. Reporting and Recommendations Module
The report and recommendations module is designed to synthesize the results from static analysis, formal verification, and simulation execution to form a detailed safety audit report and provide targeted recommendations for improvement. The main functions and processing flow of the module consist of five parts: a data extraction and processing unit, semantic analysis and comprehension unit, knowledge base integration and query unit, customized proposal generation unit, and interactive proposal optimization unit.
Initially, the data extraction and processing unit handles the extraction and consolidation of key data from these various sources. This process involves essential preprocessing tasks such as data cleaning, terminology standardization, and text normalization. Once processed, the data undergo disambiguation and lexical annotation to isolate critical information, laying the groundwork for subsequent semantic analysis.
The semantic analysis and comprehension unit then leverages advanced natural language processing technologies to convert the processed data into clear and understandable natural language descriptions. It employs text classification and clustering algorithms to categorize errors and warnings, resulting in a detailed security audit report. This report not only lists the identified issues but also assesses and classifies them based on severity, aiding developers in swiftly identifying and prioritizing key security risks.
In the knowledge base integration and query unit, a comprehensive knowledge base is integrated and queried. This knowledge base includes security best practices for smart contracts, historical remediation cases, and common vulnerability patterns. By matching the reported issues with this information, the unit derives relevant remediation strategies and recommendations, ensuring the relevance and effectiveness of the proposed solutions.
Leveraging semantic analysis results and knowledge base insights, the customized recommendation generation module formulates tailored enhancement strategies. By utilizing advanced rule engines, it constructs remediation plans to address real-world challenges. For more complex scenarios, the module synthesizes multiple knowledge sources and historical case data to deliver comprehensive solutions. These solutions may encompass code refactoring, vulnerability mitigation, and performance optimization, all with the objective of improving the security and operational efficiency of smart contracts.
Finally, the interactive suggestion optimization unit offers an interactive interface for developers to review and provide feedback on the customized suggestions. This feedback allows the unit to refine the detail and applicability of the recommendations, ensuring their practical feasibility. This interactive feature enhances the relevance and realism of the suggestions, optimizing the recommendation generation process and improving user experience.
In essence, the module produces a clear security audit report and personalized recommendations by thoroughly analyzing multiple data sources. This approach not only boosts the efficiency and accuracy of smart contract audits but also provides a solid foundation for the secure deployment and operation of smart contracts, ensuring their security and stability in diverse operating environments.
4. Experiments
This paper adopts a systematic approach to smart contract vulnerability detection. First, the types of vulnerabilities to be detected are identified, and the relevant smart contracts deployed on the test network are screened. Next, targeted vulnerability detection is performed on these contracts to analyze whether the selected vulnerability type exists. Eventually, the detection results are presented in the form of a report listing the names of all the contracts in which vulnerabilities are found. This method effectively reduces redundant detection steps, improves detection efficiency, and optimizes the detection process by making the vulnerability detection results more explicit.
4.1. Data Sources
In this experiment, we used a Python-based web crawler to gather data from Etherscan (
https://etherscan.io (accessed on 16 October 2024)) for 148 smart contracts. The crawler collected important details such as source code, ABI, binary code, and constructor parameters. Etherscan, known for its comprehensive public access to Ethereum blockchain data, is a key resource for viewing, verifying, and interacting with smart contracts, making it ideal for our data retrieval needs.
The contract selection process adhered to two main criteria. Firstly, only contracts with complete source codes were chosen to ensure the accuracy of static analysis and vulnerability detection based on the source code. Secondly, contracts were selected based on their interaction with external accounts or other smart contracts, ensuring that the interaction addresses were valid and that the operational environment in the test network accurately reflected real-world conditions.
To ensure comprehensive testing, the contracts were categorized by functionality, covering a wide range of types such as ERC-20 tokens, DeFi protocols, decentralized autonomous organizations (DAOs), and NFT contracts (
https://github.com/olstussy/Auditing (accessed on 16 October 2024)). This diverse selection provides broad coverage and ensures that vulnerability detection and analysis are representative across various application scenarios.
4.2. Experimental Procedure
The input module is tasked with receiving the source code of the smart contract for auditing purposes. This code, written in Solidity, often includes functionalities such as token transfers, permission management, and event logging.
The static analysis module uses the ACL2 8.0 to examine the Solidity code’s syntax and semantics. Configured for Solidity version 0.8.3 with all security checks enabled, this analysis is essential for detecting vulnerabilities. It focuses on evaluating the ABI and bytecode of the smart contract, establishing key mappings between the contract, its ABI functions, and the functions those ABI functions invoke. This foundational analysis is crucial for identifying potential issues and supporting the overall vulnerability detection process.
The execution of a smart contract involves transactions between distinct accounts based on the contract’s rules, including calls to ABI functions. To ensure accurate execution, it is essential to simulate these transactions with external accounts. For specific vulnerabilities, such as reentrancy, which involves complex interactions between contracts and nested function calls, standard transaction analysis may be inadequate. Consequently, proxy accounts are constructed according to defined attack scenarios to simulate and detect such vulnerabilities effectively. These proxy accounts are designed to interact in ways that can trigger reentrancy attacks, thereby identifying and highlighting contracts with such vulnerabilities. The number of smart contracts tested for different types of vulnerabilities is shown in
Table 1.
After completing the static analysis, we started to detect the vulnerability of each deployed smart contract for a specific type of vulnerability. First, a random number generator is used to generate an integer in a certain interval as the number of times the smart contract is detected, which needs to be selected in a moderate interval.
To achieve an optimal balance between detection efficiency and coverage, a function from the corresponding function call set of the smart contract is randomly selected for fuzzy input in each vulnerability detection process. Multiple random selections are involved in a vulnerability detection process, and the reason for emphasizing randomness is to maximize the coverage as well as the accuracy of vulnerability detection and to simulate the execution of the smart contract under different function call sequences by means of randomization.
Table 2 shows the number of smart contracts containing vulnerabilities detected by the static analysis module.
We tested 148 smart contracts and detected 18 smart contracts with vulnerabilities, of which three block number dependency vulnerabilities were detected and the number of actual smart contracts with block number dependency was two, with a 66.9% correct rate. Nine conditional competition vulnerabilities were detected, and the actual number of smart contracts with conditional competition vulnerabilities was six, with a 66.7% correct rate. All other smart contracts with vulnerabilities were correctly identified.
Race condition vulnerabilities are usually caused by mutual interference between multiple concurrent operations or transactions, especially when accessing shared resources; at the same time, detecting such vulnerabilities becomes more challenging due to the complexity of the block numbering dependency logic, which often leads to false positives and decreased accuracy. This is further verified by the experimental data, which shows that the detection of block number dependency vulnerabilities has a low correct rate, and this complexity makes the detection of such vulnerabilities more difficult and uncertain.
To more intuitively demonstrate the performance of the method proposed in this paper for detecting Ethereum smart contract vulnerabilities, as well as the current challenges it faces, comparative experiments were conducted, selecting relevant work in the field of smart contract vulnerability detection for evaluation. Specifically, the proposed method was compared against five mainstream vulnerability detection tools: Oyente, ReGuard, Manticore, Securify, and Slither. These tools were tested on the same dataset and for the same types of vulnerabilities. As shown in
Table 3, following the experiments, an in-depth analysis and discussion of the differences in detection results between each tool were conducted to comprehensively assess the effectiveness and performance of various detection methods in practical applications.
To streamline the experiments, we focused solely on testing for reentrant, disorder, and stack overflow vulnerabilities using a range of detection tools. The data obtained from these tests are summarized below.
Table 4 presents a thorough comparative analysis of various smart contract analysis tools, detailing their respective strengths and limitations in the context of vulnerability detection. Oyente, one of the pioneering tools in this domain, is noted for its relatively high error rate, particularly in the identification of reentrancy vulnerabilities, with a false-positive rate of 3/7. Oyente utilizes symbolic execution to traverse multiple execution paths; however, its fundamental analytical approach often results in a considerable number of false positives, reflecting the constraints of its basic methodology. Reguard demonstrates notable accuracy in detecting reentrancy vulnerabilities, excelling in this specialized area. However, its primary drawback is its narrow focus; it exclusively targets reentrancy issues and does not address other potential vulnerabilities, thereby limiting its overall applicability. Manticore can explore complex paths in-depth for reentrancy attack detection but may miss some cases due to path explosion. While it can analyze issues like order confusion and stack overflow, its effectiveness may be limited in more complex contracts. Securify quickly identifies common reentrancy patterns and sequential issues, providing clear reports, but its detection is weaker when handling dynamic calls and more complex vulnerabilities. Its stack overflow detection is constrained by the rules engine, making it difficult to catch lower-level errors. Slither, meanwhile, efficiently identifies obvious reentrancy risks and sequential problems but falls short in detecting issues in complex multi-contract interactions and deep calls. Its ability to identify stack overflow vulnerabilities is also relatively limited.
In comparison, the tool proposed in this paper demonstrates significantly higher accuracy in identifying mature vulnerabilities. It preprocesses the smart contract code at the input module stage, enabling timely detection of potential errors early in the reception process. During the static analysis phase, ACL2 is employed for an in-depth examination of Solidity’s syntax and semantics, ensuring that issues are effectively addressed before they escalate into major failures or risks. Following a comprehensive evaluation of the formal verification and simulation execution modules, the tool utilizes Spin to validate the Promela code generated from the smart contract source code. This step offers valuable insights into potential issues within the contract. Subsequently, the behavior of the smart contract under real-world operating conditions is simulated using an Ethereum simulator to further assess and validate its performance. This dual assessment method, which combines formal verification and simulation, not only enables comprehensive identification of vulnerabilities but also verifies the stability of the contract’s operation across various scenarios. As a result, it significantly enhances the overall effectiveness of vulnerability detection, providing a more reliable assurance for the security of smart contracts.
The use of the tool demonstrates excellent performance in detecting reentrancy attacks, order confusion, and stack overflow, primarily due to the combination of in-depth analysis and comprehensive static analysis. By employing formal verification and simulation execution, it is possible to thoroughly examine contract logic, identify potential errors in a timely manner, and reduce the complexity of the analysis. Additionally, ACL2 can accurately detect syntax and semantic errors in Solidity, effectively preventing order confusion and stack overflow. The Ethereum simulator’s evaluation provides insights into the contract’s performance under real-world conditions, significantly enhancing the detection capability for these vulnerabilities.
Figure 6 and
Figure 7 show some of the issues and suggestions generated by this tool after analyzing a subset of smart contracts in the current experiment.
In the security audit report, the detected issues are thoroughly described along with optimization recommendations. For instance, to address the conditional contention vulnerability, it is advised to implement a locking mechanism to prevent concurrent access to shared resources. This can be achieved by incorporating require statements to verify the contract’s state before executing critical operations. Additionally, to mitigate issues related to block numbering dependencies, it is recommended to avoid using block numbers in critical logic. Instead, utilizing timestamps or other on-chain metrics that are less susceptible to manipulation is suggested. These measures aim to enhance the security and stability of smart contracts, reduce the risk of potential attacks, and ensure the contract’s reliability across various environments. Following the suggestions provided in the report, the recommended changes were implemented, and the contract was subsequently re-audited. The contract address and link used in the experiment are shown below, and
Table 5 illustrates the results of this re-audit after the modifications were applied.
Contract Address:
0x27054b13b1b798b345b591a4d22e6562d47ea75a
Link Address:
This tool uses formal verification, static analysis, and manual review to conduct a multi-dimensional comprehensive security audit of the code specifications, security, and business logic of the smart contract in three aspects.
Table 5 shows the deployment address and relevant links for the smart contract, as well as the results of an audit conducted during the experiment. Based on the recommendations in the audit report, the source code of the smart contract was modified and resubmitted for further audit. The new security audit report indicates that all identified security issues have been effectively resolved.
5. Discussion and Limitations
The use of blockchain technology offers numerous advantages but also presents significant development challenges, particularly in the area of smart contract security auditing. Formal verification-based auditing approaches are effective in identifying security vulnerabilities and logic flaws, but they come with limitations. First, detection accuracy requires improvement due to false positives and omissions, pointing to the need for optimizing algorithms and test cases. Additionally, code coverage is insufficient, especially when dealing with complex contract logic and edge cases, highlighting the necessity to enhance both the comprehensiveness of coverage assessments and detection algorithms.
Moreover, the current approach targets only eight common vulnerabilities, limiting its ability to address the increasing variety of vulnerabilities in the rapidly evolving blockchain landscape. Expanding the detection scope is therefore essential. The method’s current focus on the Ethereum platform further underscores the need for cross-platform detection to accommodate smart contracts across different blockchain ecosystems. Although automated detection improves efficiency, manual review is still necessary to confirm vulnerabilities, which constrains both accuracy and speed. Additionally, the formal verification and simulation modules impose performance challenges, particularly with large-scale contracts, emphasizing the need for optimizations to enhance overall audit efficiency.
Furthermore, the detection rules and model updates may not adapt quickly to newly emerging attack vectors, resulting in inadequate identification of new vulnerabilities. Certain complex attack patterns, especially those involving cross-contract interactions or dynamic state changes, may exceed current analytical capabilities, making comprehensive risk capture difficult for static analysis. Additionally, static analysis faces limitations in identifying vulnerabilities that depend on specific inputs, as it relies primarily on static features of contract source code, failing to reflect dynamic changes during execution. This may lead to overlooked vulnerabilities, reducing overall detection effectiveness.
In summary, the approach requires further refinement in terms of accuracy, coverage, detection scope, and cross-platform compatibility, along with performance optimizations, to effectively address the growing complexities of smart contract security.