Smart contract fuzz testing method based on state variable parameterization

By introducing stand-alone parameters and symbol taint analysis into the function parameters of smart contracts, the problem of inefficient state exploration by existing fuzz testing tools is solved, efficient branch coverage and vulnerability detection is achieved, and the detection accuracy and reliability of smart contracts is improved.

CN120407383BActive Publication Date: 2025-08-29HANGZHOU DIANZI UNIV
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202510905375.0
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2025-07-02
Publication Date
2025-08-29
Estimated Expiration
2045-07-02

AI Technical Summary

Technical Problem

The existing smart contract fuzz testing tools are inefficient in state exploration, making it difficult to construct state variable values ​​that meet specific branch conditions, affecting the improvement of branch coverage and vulnerability detection capabilities.

Method used

By introducing stand-in parameters with the same name and type as the state variable in the function parameter, a stand-in contract is generated, and using data operation perception and symbol stain analysis to generate mutation data that meets the constraints, accurately locking state variables that affect branch conditions, a fuzz testing method based on state variable parameterization is proposed.

Benefits of technology

It significantly improves branch coverage and vulnerability detection efficiency, reduces false positive rate, and improves the accuracy and reliability of vulnerability detection of smart contracts.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120407383B_ABST
    Figure CN120407383B_ABST
Patent Text Reader

Abstract

The present invention discloses a smart contract fuzz testing method based on state variable parameterization. The method includes: a preprocessing stage, obtaining the smart contract program to be tested, compiling it using a static analysis tool, extracting compilation information, and generating state variable information based on a depth-first algorithm; a parameterization stage, initializing a population based on a genetic algorithm and performing a single round of smart contract testing, confirming the set of state variables to be parameterized, adding substitute parameters with the same name and type as the state variables, and generating a substitute contract corresponding to the original smart contract; a fuzz testing stage, checking whether the substitute parameters meet the constraints of the value range, determining whether to perform mutation, and verifying the values ​​of the substitute parameters in the seed that triggered the vulnerability during the fuzz testing of the substitute contract. The present invention uses the value range of the state variable to check the mutation data, ensuring data availability, and ensures the reliability of the detection results by inferring the state variable values ​​that triggered the vulnerability on the original contract.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the technical field of vulnerability detection for smart contracts, and in particular to a smart contract fuzz testing method based on parameterized state variables. Background Art

[0002] Fuzz testing is an automated testing technique whose core concept is to input large amounts of randomly generated, unexpected data into the target program while simultaneously collecting and monitoring abnormal information during the execution of test cases. This is done to minimize the chances of illegal input that can cause errors in the target program and identify vulnerabilities. Fuzz testing has made extensive progress in the smart contract field. Existing smart contract fuzzers such as sFuzz, Smartian, and Confuzzius have made progress in branch coverage and vulnerability detection.

[0003] A deployed smart contract is a runtime program containing persistent state variables. These state variables are referenced and read by various functions within the contract. They participate in data calculations and conditional judgments within these functions, and influence the execution flow of conditional branches. Therefore, Confuzzius proposes the concept of "state exploration." This technique leverages the read-after-write (RAW) data dependencies of state variables to guide the fuzzifier in constructing a sequence of functions that write to and then read from the state variables. This allows the fuzzifier to explore different state variable values ​​and attempt to trigger conditional branches within contract functions that contain state variables, thereby improving the branch coverage of fuzz testing.

[0004] However, state exploration methods based on constructing function sequences based on RAW data dependencies essentially execute function sequences that modify state variables, probabilistically colliding with the conditional values ​​of state variables in branch conditions. For example, when a smart contract's branch conditions require a state variable to reach a specific value or fall within a specific value range, the probability of constructing a state variable value that meets the conditions based on the function sequence generated based on RAW data dependencies is low. This limits the efficiency of state exploration, making it difficult for the fuzzer to generate seeds that meet the branch conditions, which in turn affects branch coverage and vulnerability detection capabilities.

[0005] In summary, current smart contract fuzz testing tools still face the following challenges in state exploration: the state exploration method based on random function sequences is inefficient and it is difficult to construct state variable values ​​that meet specific branch conditions. Summary of the Invention

[0006] The present invention innovatively proposes a fuzz testing method based on state variable parameterization. By introducing a substitute parameter with the same name and type as the state variable in the function input parameter to generate a substitute contract, the present invention directly integrates the value control of the state variable into the function call process, thereby realizing the precise exploration of branch conditions. Unlike the traditional method of randomly generating function sequences based on RAW data dependencies, the present invention accurately locks the state variables that affect the branch conditions through data operation perception and state variable value range extraction, and uses symbolic taint analysis to generate mutant data that meets the constraints. In addition, the present invention proposes a vulnerability verification mechanism based on function sequences, which ensures the reliability of the detection results by inferring the state variable values ​​that trigger the vulnerability on the original contract.

[0007] The fuzz testing method based on state variable parameterization mainly includes three stages: preprocessing stage, parameterization stage, and fuzz testing stage. In the preprocessing stage, the static analysis tools solcx and Slither are used to compile the smart contract, extract static opcodes, opcode-source code mapping table, application binary interface (ABI), and abstract syntax tree (AST), and generate relevant information of the state variables by analyzing the AST; in the parameterization stage, the parameterized state variable objects are first confirmed through the data operation perception method; then, substitute parameters of the same name and type of these state variables are added to the input parameters of the contract-related functions, and the value range of the state variables is obtained to realize the parameterization of the state variables; in the fuzz testing stage, mutation schemes are provided for the value range of the substitute parameters and their corresponding state variables, and the constructor sequence is constructed to verify the value of the substitute parameters after the vulnerability is detected.

[0008] The present invention provides a smart contract fuzz testing method based on state variable parameterization, which includes the following stages:

[0009] Preprocessing stage: First, obtain the smart contract program to be tested and compile it using the static analysis tools solcx and Slither to extract compilation information, including static opcodes, the mapping table source_map between opcodes and source code statements, the application binary interface (ABI), and the abstract syntax tree (AST);

[0010] Then, based on the depth-first algorithm, the AST is traversed to generate state variable information including the name, initial value and type of the state variable in the smart contract.

[0011] Parameterization phase: First, initialize the population based on the genetic algorithm and execute a single round of smart contract testing to obtain dynamic opcodes, track the SLOAD and SSTORE opcodes and their operation addresses, build a dictionary of functions to read and write state variables, and confirm the set of state variables to be parameterized;

[0012] Then, iterate over the set of state variables to be parameterized, modify the input parameters of the functions that operate on these state variables in the smart contract, add substitute parameters with the same name and type as the state variables, and generate a substitute contract corresponding to the original smart contract;

[0013] Finally, the static opcodes and source_map obtained in the preprocessing stage are used to extract the value range of the parameterized state variables.

[0014] Fuzz testing phase: First, check whether the mutation data of the substitute parameter meets the constraints of the corresponding state variable value range. If so, perform the mutation; otherwise, retain the original data;

[0015] Then, during the fuzz testing of the surrogate contract, if a potential vulnerability is detected, the values ​​of the surrogate parameters in the seed that triggers the vulnerability are verified;

[0016] Finally, if the verification fails, the triggered vulnerability will be marked as a false positive.

[0017] Preferably, the specific process of the pre-processing stage includes the following steps:

[0018] 1-1. Obtain the program to be tested, which is the smart contract code;

[0019] 1-2. Compile the program under test using a static analysis tool to obtain compilation information including static opcodes, opcode and source code statement mapping table source_map, ABI, and abstract syntax tree AST;

[0020] 1-3. Use the depth-first algorithm to search the AST and obtain the state variable information in the contract, including the state variable name, initial value initvalue, and variable type type, which are recorded in the sta_variable list, init_value dictionary, and type dictionary respectively.

[0021] Preferably, the parameterization stage can be specifically divided into the following stages: a data operation perception sub-stage, a state variable parameterization sub-stage, and a state variable range extraction sub-stage.

[0022] 2-1. The data operation and perception sub-phase includes the following steps:

[0023] 2-1-1. First, the population is initialized based on the genetic algorithm. The seeds in the population only execute a single, different contract function.

[0024] 2-1-2. Perform the first round of fuzz testing, executing each seed one by one and obtaining the dynamic opcodes executed by each function;

[0025] 2-1-3. Track the read SLOAD and store SSTORE opcodes and their addresses to retrieve the access pattern of the runtime state variables, and store them as the read state variable dictionary D of the function. read and the function's write state variable dictionary D write ;

[0026] 2-1-4. Reading the state variable dictionary D of the function read and the function's write state variable dictionary D write Take the intersection of the state variables in and get the list of state variables to be parameterized.

[0027] 2-2. The specific process of the state variable parameterization sub-phase is as follows:

[0028] 2-2-1. Traverse the state variables in the state variable list to be parameterized, in D read and D write Matches reading or writing ps i function;

[0029] 2-2-2. Modify the function matched in 2-2-1. First, use a regular expression to match the entire line of code where the function is declared. Then, use a regular expression to locate the input parameter part within the brackets in the function declaration. Finally, combine the state variable information extracted in 1-3 and add the state variable ps to the input parameter. i Parameters with the same name and type are called substitute parameters;

[0030] 2-2-3. Repeat the process of 2-2-1 and 2-2-2 until all state variables in the state variable list parastate are parameterized. At this time, the smart contract with modified source code is called a substitute contract.

[0031] 2-3. The specific process of the state variable range extraction sub-phase is as follows:

[0032] 2-3-1. Among the static opcodes, identify operations related to state variables, prioritizing the matching of addition (ADD), subtraction (SUB), multiplication (MUL), and division (DIV).

[0033] 2-3-2. For each matched operation, extract the corresponding program counter (pc), scan source_map to obtain the source code statements related to the program counter (pc), and record all the hits in the variable operation list (lines).

[0034] 2-3-3. Traverse each source code statement line in the variable operation list lines i, use regular expressions to extract the variable name name and operation step step for operation;

[0035] 2-3-4. Check that name is the state variable name contained in the state variable information in 1-3;

[0036] 2-3-5. Check the step to make sure it comes from fixed step size data or function call;

[0037] 2-3-6. Combine the state variable information in 1-3 (including name, type, initial value initvalue) with the step size step to generate a string with the value range of the state variable name in the format of opcode_type_initvalue_step; when the state variable involves multiple operations, generate multiple different value ranges and store them in the corresponding list RangeList i =[opcode i1 _type i _initvalue i _step i1 ,…,opcode in _type i _initvalue i _step in All state variables and their corresponding value range lists are integrated into the dictionary RangeDict={name1:RangeList1,…, name n :RangeList n};

[0038] 2-3-7. Using the stand-in contract as the program under test, regenerate the population and enter the fuzz testing loop.

[0039] Preferably, the fuzzy testing phase can be specifically divided into the following phases: substitute parameter mutation phase and vulnerability verification phase

[0040] 3-1. The avatar parameter mutation stage specifically includes the following steps:

[0041] 3-1-1. Initialize a mutation pool to store the mutation values ​​solved by symbolic taint analysis; the mutation pool supports the reuse of legal values ​​solved by symbols in subsequent steps during testing to replace the current values ​​of the stand-in parameters;

[0042] 3-1-2. For the executed seed, analyze its opcode sequence, program counter, and execution stack, identify opcodes related to data transfer, inject taints, and track their propagation in the stack and memory, generate symbolic constraints, use the symbolic solver to solve the symbolic constraints, and store the results in the mutation pool.

[0043] 3-1-3. For the seed to be mutated, select a mutation value from the mutation pool as the surrogate parameter value of the current seed. Or, if the mutation pool is empty, generate a random value based on the variable type of the surrogate parameter as the mutation value.

[0044] 3-1-4. Check the validity of the mutation value to ensure that it complies with the state variable value range extracted in stage 2-3. If the validity check passes, the mutation value is assigned to the stand-in parameter, generating a new test case. If the validity check fails, a random value is generated based on the variable type of the stand-in parameter and the range check is repeated.

[0045] 3-2. The vulnerability verification phase includes the following steps:

[0046] 3-2-1. Construct a two-dimensional effect array Effect: Extract the function name list F=[f1,f2,…,f m ], for each function f i , check whether it modifies the state variable s in the state variable list sta_variable generated in the preprocessing stage j , extract the value initvalue from the value range corresponding to the state variable ij , Operation type op ij (such as ADD, SUB, MUL or DIV) and step size step ij , recorded as Effect[f i ][s j ]=(op ij , step ij , initvalue ij ), represents the i-th function f i For the jth state variable s j The modification method is to use initvalue ij is the initial value, step ij The step length of op ij Operation;

[0047] 3-2-2. When a vulnerability is detected in a stand-in contract, extract the name and value of the stand-in parameter in the test case that triggered the vulnerability and record the target value of the corresponding state variable;

[0048] 3-2-3. Using the pre-built effect array Effect, find a function sequence that can make the state variables in the original contract reach the target value; the sequence consists of function calls that affect the state variables and satisfy the operation type and step size constraints in Effect;

[0049] 3-2-4. If the function sequence is successfully solved, deploy the original contract on the virtual machine and use the sequence to test the original contract to see if the same vulnerability can be triggered. If so, the vulnerability is confirmed to be true. If the sequence cannot be constructed or the test results are inconsistent, mark the vulnerability as a false positive.

[0050] The present invention has the following characteristics and beneficial effects:

[0051] (1) The present invention proposes a method for parameterizing state variables. Based on the state variables, a function input called a substitute parameter is added to the function of the original contract to obtain a substitute contract, which replaces the original contract and enters the fuzzy testing cycle.

[0052] (2) The present invention proposes a mutation strategy for adaptive surrogate parameters, which uses the value range of state variables to check the mutation data and ensure data availability.

[0053] (3) Based on the state variable parameterization method, the present invention proposes a vulnerability verification method. After the vulnerability is detected on the substitute contract, the function sequence that triggers the same branch is deduced on the original contract to prove that the vulnerability originates from the original contract. BRIEF DESCRIPTION OF THE DRAWINGS

[0054] Figure 1 This is the overall flow chart of the smart contract fuzz testing method based on state variable parameterization of the present invention;

[0055] Figure 2 This is a flow chart of the substitute parameter mutation phase of the smart contract fuzz testing method based on state variable parameterization of the present invention;

[0056] Figure 3 This is a flow chart of the vulnerability detection phase of the smart contract fuzz testing method based on state variable parameterization of the present invention; DETAILED DESCRIPTION

[0057] The present invention is described in detail below in conjunction with specific embodiments. The following examples will help those skilled in the art to further understand the invention, but are not intended to limit the present invention in any form. It should be noted that, in the absence of conflict, the embodiments of the present invention and the features in the embodiments can be combined with each other.

[0058] like Figure 1 As shown in Figure 1, the smart contract fuzz testing method based on state variable parameterization includes a preprocessing phase, a parameterization phase, and a fuzz testing phase, wherein:

[0059] During the preprocessing phase, the program under test is first compiled using the static analysis tools solcx and Slither to obtain contract compilation information, including static opcodes, a mapping table of opcodes to source code, the ABI, and the abstract syntax tree (AST). The AST is then parsed using a depth-first search algorithm to obtain the names, initial values, and variable types of the contract's state variables, collectively referred to as state variable information.

[0060] In the parameterization stage, the seeds are first initialized based on the genetic algorithm, and each seed only executes a single contract function; then a single round of fuzz testing is performed to obtain the dynamic opcodes of each function, and the SLOAD and SSTORE opcodes and the addresses of their operations are tracked to retrieve the access patterns of runtime state variables; then, based on the state variables read and written by the tracked functions and the state variable information in the preprocessing stage, the set of state variables to be parameterized is identified through data operation perception, the relevant functions are modified, and substitute parameters with the same name and type as the state variables are added to obtain the substitute contract; then the addition, subtraction, multiplication and division operations of the static opcodes are identified, the source code is located in combination with the mapping table, and the value range of the state variables is extracted; finally, the seed of the substitute contract is initialized based on the genetic algorithm.

[0061] During the fuzz testing phase, symbolic taint analysis is first used to generate mutation values. The surrogate parameters are then subjected to targeted mutations, and the corresponding state variable value ranges are checked. Finally, when a vulnerability is detected, the surrogate parameter values ​​that trigger the vulnerability are extracted and the original contract function sequence is reversed for verification. If verification passes, the vulnerability is confirmed as a true positive; otherwise, it is marked as a false positive.

[0062] I. The pretreatment stage of the present invention specifically comprises the following steps:

[0063] Obtain the program to be tested, which is the smart contract code written in Solidity to be tested;

[0064] Use static analysis tools solcx and Slither to compile the program to be tested, and obtain compilation information including static opcodes, opcode and source code statement mapping table source_map, ABI and abstract syntax tree AST;

[0065] Use a depth-first algorithm to search the AST to obtain the names, initial values, and variable types of the state variables in the contract. First, traverse the key-value pairs of the AST. A key is a node attribute name (such as "type" or "name"), and a value is the corresponding value. Then, check whether the value of the current node is "VariableDeclaration," indicating that the node is a variable declaration node. Add the variable name to the sta_variable list, add its corresponding initial value to the init_value dictionary as a key-value pair, and add its corresponding variable type to the type dictionary as a key-value pair. Finally, recursively execute this method, using the current node's value as the new AST input, and continue traversing the child nodes. The resulting set of state variable names, initial values, and variable types is collectively referred to as state variable information.

[0066] II. The parameterization phase of the present invention specifically includes the following steps: a data operation perception phase, a parameterization phase, and a state variable range extraction phase.

[0067] 2-1. In the data operation perception phase, the population is initialized based on the genetic algorithm, and the first round of fuzz testing is performed. The dynamic operation code of each function execution is obtained, and the list of state variables to be parameterized is obtained. The specific steps include the following:

[0068] 2-1-1. For a smart contract with m functions to be tested, first initialize the population population = {seed1,seed2,…,seed m The population consists of m initialization seeds. Confuzzius defines each seed as consisting of a function sequence. The function sequence of the initialization seed contains only a single, non-repeating function and randomly generates input data based on the parameter types of each function in the ABI.

[0069] 2-1-2. Perform the first round of fuzz testing, executing each seed one by one and obtaining the dynamic opcodes executed by each function;

[0070] 2-1-3. Track the read SLOAD and store SSTORE opcodes and their addresses to retrieve the access pattern of runtime state variables. This records the state variables read (SSLOAD) and written (SSTORE) by each function in the contract and stores them as the function's read state variable dictionary D read and the function's write state variable dictionary D write ;

[0071] 2-1-4. Reading the state variable dictionary D of the function read and the function's write state variable dictionary D writeTake the intersection of the state variables in the contract, count the state variables that can be read and written in the contract, and record them as the state variable list to be parameterized parastate=[ps1,ps2,…ps m ].

[0072] 2-2. In the parameterization phase, the state variables in the state variable list are traversed, function matching is performed, and input parameters with the same name and type as the state variables are added to the input parameters to obtain the substitute contract. The specific steps include:

[0073] 2-2-1. Traverse the list of state variables to be parameterized parastate obtained in 2-1-3. For each state variable to be parameterized psi, traverse the read state variable dictionary D in 2-1-2 read and the function's write state variable dictionary D write , matches the function that reads or writes the state variable psi;

[0074] 2-2-2. Modify the function matched in stage 2-2-1. First, use the regular expression re.compile(r"function\s+(\w+)\s*\(([^)]*)\)\s*(public|external|internal|private)?\s*{?") to match the entire line of code where the function is declared; then use the regular expression re.compile(r"\(([^)]*)\)") to further locate the input parameter part within the brackets in the function declaration; finally, confirm the ps based on the state variable information extracted in 1-3. i The variable type is added in the input parameter with the state variable ps i The input parameters with the same name and type are called substitute parameters, and the modified function is the substitute function of the original function;

[0075] 2-2-3. Repeat the process from 2-2-1 to 2-2-2 until all state variables in the state variable list parastate are parameterized. At this point, the smart contract with modified source code is called a substitute contract.

[0076] 2-3. In the state variable range extraction phase, in the static opcode sequence, operations related to the state variables are identified, the corresponding program counters are extracted, the variable names and operation steps for the operations are extracted, and the population is regenerated using the stand-in contract as the program under test. The specific steps include:

[0077] 2-3-1. Based on statistical analysis of smart contract state variable operations, match the four opcodes: addition (ADD), subtraction (SUB), multiplication (MUL), and division (DIV), as they appear most frequently in state variable modifications. In the static opcode sequence in 1-1, identify the four operations mentioned above. For each identified opcode, check whether its preceding and succeeding instructions contain EQ instructions to determine whether the operation affects the judgment of branch conditions;

[0078] 2-3-2. For each matched operation, extract the corresponding program counter (pc), scan source_map to obtain the source code statement (line) associated with the program (pc), and record all hits in the variable operation list (lines).

[0079] 2-3-3. Traverse each source code statement line in the variable operation list lines to extract the variable name and operation step of the operation. First, call .lstrip() to remove the blank characters of line, intercept the first 6 characters of the statement ([0:6]), and record it as the code field; then define the regular expression re.compile(code + ".*?" + ";") to determine the code line result that modifies the variable in line; then traverse the characters of result to see if it contains the addition (+), subtraction (-), multiplication (*), and division ( / ) operators. For code lines that do not contain them, no further analysis will be performed; finally, define four types of regular expressions re.compile(r'[\w]+'), re.compile(r'[\w]-'), re.compile(r'[\w]*'), and re.compile(r'[\w] / ') to extract the operand name name and operation step step of four different operations;

[0080] 2-3-4. Check name, match name with the state variable information obtained in 1-3, traverse all keys in the state variable information dictionary in step 1-3, and determine whether it is equal to the variable name extracted in step 2-3-3. Confirm that the variable performing the operation is a state variable, not a temporary variable or function parameter;

[0081] 2-3-5. Check step. First, determine whether step is msg.value or a function name in the ABI. If so, set the value of step to r, indicating random. Finally, determine whether step is a number. If so, keep it; otherwise, discard the value range.

[0082] 2-3-6. After checking name and step, combine the state variable information in 1-3 (name, type, initial value initvalue) and step size step to generate a string with the value range of the state variable name in the format of opcode_type_initvalue_step; when a state variable name i When multiple operations are involved, multiple different value ranges are generated and stored in the corresponding list RangeList i =[opcode i1 _type i _initvalue i _step i1 ,…,opcode in _type i _initvalue i _step in All state variables and their corresponding value range lists are integrated into the dictionary RangeDict={name1:RangeList1,…, name n :RangeList n};

[0083] 2-3-7. Using the stand-in contract as the program to be tested, regenerate the population according to the method in 2-1-1 and enter the fuzz testing phase.

[0084] III. The fuzzy testing phase of the present invention, such as Figure 2 As shown, the specific steps include: substitute parameter mutation stage and vulnerability verification stage.

[0085] 3-1. In the surrogate parameter mutation phase, the mutation pool is initialized. For the executed seed, taints are injected to generate symbolic constraints. The symbolic constraints are solved using a symbolic solver and the results are stored in the mutation pool. For the seed to be mutated, random values ​​are generated as mutation values ​​based on the variable type of the surrogate parameter and a validity check is performed. The specific steps include:

[0086] 3-1-1. Initialize a mutation pool to store the mutation values ​​solved by symbolic taint analysis; the mutation pool supports reusing previously solved legal values ​​to replace the current values ​​of the stand-in parameters during testing;

[0087] 3-1-2. For the executed seed, analyze its opcode sequence, identify data transfer-related opcodes (such as CALLDATALOAD and CALLVALUE), inject taints, and track their propagation through the stack, memory, and storage. Generate symbolic constraints and solve them using a symbolic solver (such as Z3). Obtained mutation values ​​are stored in a list of corresponding variables in the mutation pool.

[0088] 3-1-3. For the seed to be mutated, select a mutation value from the mutation pool as the surrogate parameter value of the current seed. Or, if the mutation pool is empty, generate a random value based on the variable type of the surrogate parameter as the mutation value.

[0089] 3-1-4. Check the validity of the mutation value used. Look up the range of opcode_type_initvalue_step for the state variable with the same name as the stand-in parameter. The range is the hash value of the opcode operation with initvalue as the initial value and step as the step length. If there are multiple ranges, the check passes if any one of them is met. If the validity check passes, assign the mutation value to the stand-in parameter. If the validity check fails, discard the data, generate a random value based on the stand-in parameter's variable type, and repeat the range check.

[0090] 3-2. Vulnerability detection stage, such as Figure 3 As shown in the figure, a two-dimensional impact array is constructed. When a vulnerability is detected on the substitute contract, the names and values ​​of the substitute parameters in the test case that triggers the vulnerability are extracted, and the target values ​​of the corresponding state variables are recorded. Using the impact array, a function sequence that can make the state variables in the original contract reach the target values ​​is solved to observe whether the same vulnerability can be triggered and verify it. The specific steps include the following:

[0091] 3-2-1. Construct a two-dimensional effect array Effect: Extract the function name list F=[f1,f2,…,f m ], for each function f i , check whether it modifies the state variable s in the state variable list sta_variable generated in the preprocessing stage j , extract the value initvalue from the value range corresponding to the state variable ij , Operation type op ij (such as ADD, SUB, MUL or DIV) and step size step ij , recorded as Effect[f i ][s j ]=(op ij , step ij , initvalue ij ), represents the i-th function fi For the jth state variable s j The modification method is to use initvalue ij is the initial value, step ij The step length of op ij Operation;

[0092] 3-2-2. When a surrogate contract detects a vulnerability, it extracts the name and value of the surrogate parameter in the test case that triggered the vulnerability and records it as the target value that the corresponding state variable needs to reach;

[0093] 3-2-3. Use the pre-built effect array Effect to solve the function sequence that makes the state variable in the original contract reach the target value. Traverse the effect array Effect and identify the functions that affect the target state variable and their operation type and step size. Initialize an empty function sequence, iteratively add function calls, and update the state variable value based on the operation type and step size. Verify whether the sequence makes the state variable reach the target value. If there are multiple feasible sequences, give priority to the function sequence with the least number of calls. If the target state variable has multiple value ranges, construct an operation combination space. Take the operation type and step size of each constraint as an independent path, determine the possible operation sequence combination to reach the target value, and obtain the corresponding function sequence;

[0094] 3-2-4. If the function sequence is successfully solved, the original contract is deployed on the virtual machine and tested using the sequence to see if the same vulnerability can be triggered. If so, the vulnerability is confirmed to be true. If the function sequence cannot be constructed or the test results are inconsistent, the vulnerability is marked as a false positive.

[0095] Experimental results:

[0096] To validate the effectiveness of our proposed method, we conducted three sets of experiments, comparing our method, ParaFuzz, with the leading smart contract fuzzer Confuzzius and a ParaFuzz variant. The results were evaluated on two datasets. The first dataset consisted of 448 smart contracts, collected from the blockchain explorer Etherscan and other datasets used by fuzzers. The second dataset consisted of 10 smart contracts containing only single-state variables and 6 with multiple state variables, selected from the blockchain explorer Etherscan.

[0097] The variant fuzzer is ParaFuzz-NP, which removes the function of substitute parameter mutation, making the data operation-aware state variable parameterization result invalid. It is used to evaluate the effectiveness of ParaFuzz's state variable parameterization method.

[0098] Experiment 1: On Dataset 1, ParaFuzz identified a greater number of vulnerabilities, detecting 394 of the five vulnerability types—reentrancy (RE), integer overflow (OF), assertion failure (AF), block dependency (BD), and unprotected self-destruction (US), representing 87.9% of the total 448 detected. This represents a 57.8% improvement over Confuzzius. ParaFuzz significantly improved recall for all five vulnerability types, with a maximum difference of 72% and a minimum difference of 38%. Its accuracy for all five vulnerability types exceeded 90%, with a maximum difference of 36.4% and a minimum difference of 13.5% compared to Confuzzius.

[0099] Experiment 2: On Dataset 1, the total testing time for ParaFuzz was 2214.19 seconds, while that for ConFuzzius was 949.23 seconds, a difference of 3.53 times. The average vulnerability detection time for ParaFuzz was 16.4 seconds, while that for ConFuzzius was 2.4 seconds, a difference of nearly 6.83 times. The generated "unique test cases" were then analyzed, as these test cases can drive the fuzz tester to explore new execution paths. ConFuzzius generated unique test cases at a lower rate and required more unique test cases per vulnerability detection on average. Finally, branch coverage was calculated, showing that ParaFuzz's smart contract coverage was over 10% higher than ConFuzzius's. Furthermore, ParaFuzz reached its highest coverage in significantly less time than ConFuzzius, and its branch coverage consistently grew faster than ConFuzzius's. These improvements further demonstrate the effectiveness of our approach.

[0100] Experiment 3: The ablation effect of the state variable parameterization strategy is shown in Table 1.

[0101] Table 1. Executable rate of programs after repair

[0102]

[0103] The alias parameter mutation function has been removed from ParaFuzz, making it impossible to invalidate the results of state variable parameterization. ParaFuzz-NP and ParaFuzz are tested on Dataset 1.

[0104] In terms of the recall rate of ParaFuzz in detecting reentrancy vulnerabilities, integer overflow vulnerabilities, assertion failure vulnerabilities, block dependency vulnerabilities, and unprotected self-destruction vulnerabilities, ParaFuzz is approximately 2%, 0%, 2%, 1%, and 0% higher than ParaFuzz-NP respectively; in terms of the precision of the five vulnerability detections, ParaFuzz is approximately 29%, 19%, 23%, 12%, and 19% higher than ParaFuzz-NP respectively.

[0105] Experiment 3: The vulnerability verification strategy detection results are shown in Table 2:

[0106] Table 2 Vulnerability verification strategy detection results

[0107]

[0108] The number of vulnerabilities detected and successfully verified in Dataset 2. All vulnerabilities can be successfully verified on contracts containing a single state variable; most vulnerabilities are successfully verified on contracts containing multiple state variables.

[0109] Result analysis:

[0110] The state variable parameterization strategy significantly improves ParaFuzz's ability to break through branches. By solving branch condition constraints and performing targeted mutations on stand-in parameters, ParaFuzz efficiently explores the state space of smart contracts and quickly constructs seeds that satisfy branch conditions. Compared to methods that generate function sequences based on raw data dependencies, this strategy reduces the generation of invalid seeds, significantly improving branch coverage and testing efficiency.

[0111] ParaFuzz provides an efficient vulnerability verification mechanism. For smart contracts involving only a single state variable, ParaFuzz accurately verifies vulnerabilities, significantly reducing false positives. For complex contracts with multiple state variables, ParaFuzz verifies the target values ​​of state variables by constructing function call sequences, demonstrating excellent verification results. This mechanism effectively reduces the number of false positives and improves the accuracy and reliability of vulnerability detection.

[0112] The above illustrates and describes the basic principles, main features, and advantages of the present invention. Those skilled in the art should understand that the present invention is not limited to the foregoing embodiments. The foregoing embodiments and descriptions are merely preferred examples of the present invention and are not intended to limit the present invention. Various modifications and improvements may be made to the present invention without departing from the spirit and scope of the present invention, and such modifications and improvements fall within the scope of the invention as claimed. The scope of protection claimed in the present invention is defined by the appended claims and their equivalents.

Claims

1. A smart contract fuzz testing method based on state variable parameterization, characterized in that: The following stages are included: Preprocessing stage: Obtain the smart contract program to be tested, compile it using static analysis tools, extract compilation information, and generate state variable information based on the depth-first algorithm; Parameterization phase: Initialize the population based on the genetic algorithm and perform a single round of smart contract testing to confirm the set of state variables to be parameterized, add substitute parameters with the same name and type as the state variables, and generate a substitute contract corresponding to the original smart contract; Fuzz testing phase: Check whether the substitute parameters meet the value range constraints and determine whether to perform mutations. During the fuzz testing process of the substitute contract, verify the values ​​of the substitute parameters in the seed that triggers the vulnerability.

2. The smart contract fuzz testing method based on state variable parameterization according to claim 1 is characterized in that: The specific process of the pre-processing stage is as follows: S1-1. Obtain the program to be tested, which is the smart contract code; S1-2 using a static analysis tool to compile the program under test, to obtain compilation information including static opcodes, opcodes and source code statement mapping table source_map, ABI and abstract syntax tree AST; S1-3. Use the depth-first algorithm to search the AST and obtain the state variable information in the contract, including the state variable name, initial value initvalue, and variable type.

3. The smart contract fuzz testing method based on state variable parameterization according to claim 2 is characterized in that: The parameterization phase includes: a data operation perception sub-phase, a state variable parameterization sub-phase, and a state variable range extraction sub-phase. The specific implementation process is as follows: S2-1. Data Operation Perception Sub-Phase: Initialize the population based on the genetic algorithm and perform the first round of fuzz testing to obtain the dynamic operation code of each function execution and obtain the list of state variables to be parameterized. S2-2. State variable parameterization sub-phase: Traverse the state variables in the state variable list, perform function matching, and add input parameters with the same name and type as the state variable to obtain a substitute contract; S2-3. State variable range extraction sub-phase: In the static opcode sequence, identify the operations related to the state variables, extract the corresponding program counter, extract the variable name and operation step size for the operation, and regenerate the population using the stand-in contract as the program under test.

4. The smart contract fuzz testing method based on state variable parameterization according to claim 3 is characterized in that: The data operation perception sub-stage is specifically implemented as follows: S2-1-1. Initialize the population based on the genetic algorithm, and the seeds in the population execute different single contract functions; S2-1-2. Perform the first fuzzing loop, executing each seed one by one and obtaining the dynamic opcodes executed by each function. S2-1-3. Track the read SLOAD and store SSTORE opcodes and their addresses, retrieve the access patterns of runtime state variables, and store them as the read state variable dictionary D of the function. read and the function's write state variable dictionary D write ; S2-1-4. Reading state variable dictionary D for function read and the function's write state variable dictionary D write Take the intersection of the state variables in and get the list of state variables to be parameterized.

5. The smart contract fuzz testing method based on state variable parameterization according to claim 4 is characterized in that: The state variable parameterization sub-stage is specifically implemented as follows: S2-2-1. Traverse the state variables in the list of state variables to be parameterized, and read and D write Matches functions that read or write state variables; S2-2-2. Modify the function matched in S2-2-1. First, use a regular expression to match the code where the function is declared. Then use regular expressions to locate the input parameter part in the function declaration; finally, combine the state variable information and add an input parameter with the same name and type as the state variable to the input parameter, which is called a substitute parameter; S2-2-3. Repeat the process of S2-2-1 and S2-2-2 until all state variables in the state variable list are parameterized. At this point, the smart contract with modified source code is called a substitute contract.

6. The smart contract fuzz testing method based on state variable parameterization according to claim 5 is characterized in that: The state variable range extraction sub-stage is specifically implemented as follows: S2-3-1. Identify operations related to state variables in static opcodes, prioritizing addition, subtraction, multiplication, and division. S2-3-2. For each matched operation, extract the corresponding program counter, scan the source_map to obtain the source code statements associated with the program counter, and record all hits in the variable operation list. S2-3-3. Traverse each source code statement in the variable operation list and use regular expressions to extract the variable name and operation step size to be operated. S2-3-4. Check that name is the state variable name contained in the state variable information. Check that step is derived from fixed step size data or a function call. S2-3-5. Combine the state variable information and the step size step, and generate a string in the format of opcode_type_initvalue_step based on the state variable name; When the state variable involves multiple operations, multiple different value ranges are generated and stored in the corresponding list RangeList i =[opcode i1 _type i _initvalue i _step i1 ,…,opcode in _type i _initvalue i _step in ]; All state variables and their corresponding value range lists are integrated into the dictionary RangeDict={name1:RangeList1,…, name n :RangeList n }; S2-3-7. Using the stand-in contract as the program under test, regenerate the population and enter the fuzz testing loop.

7. The smart contract fuzz testing method based on state variable parameterization according to claim 6 is characterized in that: The specific implementation process of the fuzz testing phase is as follows: S3-1. Initialize the mutation pool. For the executed seed, inject taints to generate symbolic constraints. Use the symbolic solver to solve the symbolic constraints and store the results in the mutation pool. For the seed to be mutated, generate random values ​​as mutation values ​​based on the variable type of the surrogate parameter and perform a validity check. S3-2. Construct a two-dimensional impact array. When a vulnerability is detected in a stand-in contract, extract the names and values ​​of the stand-in parameters in the test case that triggered the vulnerability, record the target values ​​of the corresponding state variables, and use the impact array to solve the function sequence that can make the state variables in the original contract reach the target values. Observe and verify whether it can trigger the same vulnerability.

8. The smart contract fuzz testing method based on state variable parameterization according to claim 7 is characterized in that: The specific implementation process of S3-1 is as follows: S3-1-1. Initialize the mutation pool to store the mutation values ​​solved by symbolic taint analysis. The mutation pool supports the reuse of legal values ​​solved by symbols in subsequent steps during testing to replace the current values ​​of the stand-in parameters. S3-1-2. For the executed seed, analyze its opcode sequence, program counter, and execution stack, identify opcodes related to data transfer, inject taints, and track their propagation in the stack and memory, generate symbolic constraints, use the symbolic solver to solve the symbolic constraints, and store the results in the mutation pool. S3-1-3. For the seed to be mutated, select a mutation value from the mutation pool as the surrogate parameter value for the current seed. If the mutation pool is empty, generate a random value based on the variable type of the surrogate parameter as the mutation value. S3-1-4. Perform a validity check on the mutation value to ensure that it complies with the state variable value range extracted in S2-3. If the validity check passes, assign the mutation value to the stand-in parameter to generate a new test case. If the validity check fails, generate a random value based on the variable type of the stand-in parameter and repeat the range check.

9. The smart contract fuzz testing method based on state variable parameterization according to claim 8 is characterized in that: The specific implementation process of S3-2 is as follows: S3-2-1. Construct a two-dimensional effect array Effect: extract the function name list F=[f1,f2,…,f m ], for each function f i , check whether it modifies the state variable in the state variable list generated in the preprocessing stage, and extract the value initvalue from the value range corresponding to the state variable ij , Operation type op ij and step length ij , recorded as Effect[f i ][s j ]=(op ij , step ij , initvalue ij ), represents the i-th function f i For the jth state variable s j The modification method is to use initvalue ij is the initial value, step ij The step length of op ij Operation; S3-2-2. When a vulnerability is detected in a stand-in contract, extract the names and values ​​of the stand-in parameters in the test case that triggered the vulnerability and record the target values ​​of the corresponding state variables. S3-2-3. Using the effect array, find a function sequence that can bring the state variables in the original contract to the target value. This function sequence consists of function calls that affect the state variables and satisfy the operation type and step size constraints in the effect. S3-2-4. If the function sequence is successfully solved, deploy the original contract on the virtual machine and use the sequence to test the original contract to see if the same vulnerability can be triggered. If so, the vulnerability is confirmed to be true. If the sequence cannot be constructed or the test results are inconsistent, the vulnerability is marked as a false positive.

Citation Information

Patent Citations

  • EOSIO smart contract-oriented grey box fuzzy test method

    CN115438351A

  • Vulnerability detection method and device for smart contract

    CN116644435A