|
ESBMC
Efficient SMT-based Context-Bounded Model Checker
|
Files | |
| pattern_check.cpp | |
| Implementation of pattern-based vulnerability detection. | |
| pattern_check.h | |
| Pattern-based vulnerability detection for Solidity contracts. | |
| solidity_convert.cpp | |
| Top-level conversion driver and static member initialization. | |
| solidity_convert.h | |
| Core AST-to-irep2 converter for the Solidity frontend. | |
| solidity_convert_builtin.cpp | |
| Built-in function and low-level call handling for the Solidity frontend. | |
| solidity_convert_call.cpp | |
| Function call conversion for the Solidity frontend. | |
| solidity_convert_constructor.cpp | |
| Constructor conversion for the Solidity frontend. | |
| solidity_convert_contract.cpp | |
| Contract-level conversion for the Solidity frontend. | |
| solidity_convert_decl.cpp | |
| Declaration conversion for the Solidity frontend. | |
| solidity_convert_expr.cpp | |
| Expression conversion for the Solidity frontend. | |
| solidity_convert_inheritance.cpp | |
| Contract inheritance handling for the Solidity frontend. | |
| solidity_convert_literals.cpp | |
| Literal conversion for the Solidity frontend. | |
| solidity_convert_mapping.cpp | |
| Mapping type conversion for the Solidity frontend. | |
| solidity_convert_modifier.cpp | |
| Function and modifier definition conversion for the Solidity frontend. | |
| solidity_convert_ref.cpp | |
| Reference and symbol resolution for the Solidity frontend. | |
| solidity_convert_stmt.cpp | |
| Statement conversion for the Solidity frontend. | |
| solidity_convert_tuple.cpp | |
| Tuple expression conversion for the Solidity frontend. | |
| solidity_convert_type.cpp | |
| Type conversion for the Solidity frontend. | |
| solidity_convert_util.cpp | |
| Utility and helper functions for the Solidity converter. | |
| solidity_grammar.cpp | |
| Implementation of Solidity grammar classification functions. | |
| solidity_grammar.h | |
| Solidity grammar enumerations and classification helpers. | |
| solidity_language.cpp | |
| Implementation of the Solidity language frontend. | |
| solidity_language.h | |
| Solidity language frontend interface for ESBMC. | |
| typecast.cpp | |
| Implementation of Solidity type casting utilities. | |
| typecast.h | |
| Type casting utilities for the Solidity frontend. | |
The ESBMC Solidity frontend accepts smart contracts written in the Solidity language together with the Solidity AST (in compact JSON form). Based on these inputs, the frontend translates the contract into a C++-style intermediate representation and automatically generates a verification harness (a main function). The generated program is then verified by ESBMC's backend.
Pass a .sol file directly to ESBMC — it will automatically find and invoke solc:
ESBMC searches for solc in this order: --solc-bin <path> > $SOLC environment variable > solc in $PATH. You can specify a particular solc binary:
You can also generate the AST yourself and pass both files:
Note that different versions of solc may produce slightly different AST formats and also support different Solidity syntaxes. The frontend is currently developed and tested against Solidity 0.8.0.
As with ESBMC in general, ESBMC-Solidity supports common bug classes, including arithmetic overflow/underflow, division by zero, null-dereference, array-out-of-bounds, assertion violations, etc. Use ESBMC command-line options to enable or configure specific checks (e.g. overflow checks, pointer checks, etc.).
Additionally, ESBMC-Solidity provides the --reentry-check option to detect potential reentrancy behaviors. When enabled, the frontend inserts assertions and instrumentation to capture possible reentrant call traces.
Note that a reported reentrancy behavior is an indicator (possible reentrancy path) and does not necessarily imply a concrete exploit (for example, actual loss of funds). The report should be inspected together with the generated counterexample trace.
By default ESBMC-Solidity analyses every contract present in the provided source program. To restrict verification to a specific contract, use:
To set multiple contracts:
To further restrict the analysis to a particular function, use:
--function can be used without --contract, but this is not recommended because specifying --contract disambiguates overloaded / similarly-named functions across contracts. The constraints on contract and function targets help reduce overhead and improve performance.
The solidity frontend can construct different main harnesses depending on the selected mode. The harness determines how external calls, addresses and inter-contract interactions are modelled, which in turn affects verification purpose and outcomes.
Flag:
Description: This is the default mode. External calls and addresses that are not otherwise constrained are modelled symbolically — the verifier makes no assumption about the code behind an external (symbolic) address, preserving soundness.
Flag:
Description: Enabling this mode switches the frontend into bounded cross-contract reasoning. In this mode, certain symbolic addresses can be bound to known contracts (or to a finite set of contracts). This enables the verifier to model inter-contract calls as concrete jumps to the bound implementations and to generate precise traces that reflect real cross-contract interactions (e.g., attacker contracts interacting with a vulnerable contract or reentrancy scenarios).
This mode is particularly useful for analysing the behaviour of a multi-contract system. Use --contract to specify the target contract(s), and --function to set the entry point.
ESBMC models keccak256, sha256, ripemd160, ecrecover, blockhash, and blobhash as nondeterministic (nondet) functions: each call returns a fully unconstrained symbolic value. The real hash algorithm is not computed.
This is an over-approximation — the verifier considers every possible return value, including the real one. Consequences:
The operational models are in src/c2goto/library/solidity/solidity_builtins.c.