---
title: Belobog Concolic Executor
url: https://www.emergentmind.com/topics/concolic-executor-in-belobog
type: topic
---

# Belobog Concolic Executor

The concolic executor in Belobog is a specialized symbolic-plus-concrete execution engine integrated into a type-aware fuzzing framework for Move smart contracts. It systematically augments coverage by combining concrete transaction execution with symbolic reasoning and SMT-guided mutation, enabling Belobog to synthesize well-typed transactions that traverse deep, value-dependent paths often invisible to random or purely type-graph fuzzing. This capability is key for detecting and reproducing exploits in deployed Move modules, particularly where strict type constraints intersect with intricate arithmetic or resource logic, as demonstrated in the reproduction of the Cetus and Nemo attacks [2512.02918].

## 1. Architectural Role and Workflow in Belobog

The concolic executor operates as an intermediary between Belobog’s type-graph-driven transaction generator and the MoveVM execution environment. After transaction construction with strict adherence to Move type and resource semantics, the executor initiates a dual execution of the transaction: one along the concrete path and another overlaying symbolic expressions for all primitive arguments. This dual execution produces both coverage feedback and path constraints. If the run uncovers new branch opportunities (via previously unseen coverage or branch inversion), the executor may synthesize mutated transactions—using solver outputs—and feeds these into the seed corpus that guides subsequent fuzzing passes.

## 2. Formal Model: Symbolic States and Path Constraints

Each MoveVM state during concolic execution is paired with a symbolic overlay. Formally:
- $\sigma \in \Sigma$, the symbolic state, maps each live variable to a symbolic expression over uninterpreted symbols $\alpha_1, \alpha_2, \ldots$ and concrete constants.
- $\Pi$, the path constraint, encodes the conjunction of Boolean formulas required for the path traversed thus far.
- The concolic state is a pair $(c, (\sigma, \Pi))$, where $c$ is the concrete VM state (stack, locals, memory).

Bytecode execution proceeds by updating both $c$ and $(\sigma, \Pi)$ for each Move instruction:
- For non-branching opcodes: variables are updated via symbolic operators, and overflow guards (e.g., $e_1 + e_2 < 2^{64}$) are appended to $\Pi$.
- For conditional branches: both the concrete result and symbolic condition formula are recorded, and $\Pi$ is extended with either the positive or negated symbolic branch constraint.

These constraints are encoded in bit-vector (BV) theory for SMT solving and are always type-checked against Move’s type system to preclude ill-typed mutations [2512.02918].

## 3. Core Algorithms for Concolic Execution

The executor consists of three principal algorithmic phases:

### Symbolic Run and Constraint Collection
A transaction $T$ initiated with concrete inputs $v$ and symbolic names $\alpha$ proceeds instruction by instruction, collecting branch sites and symbolic constraints into a log and updating coverage bitmaps. Branch conditions record both the symbolic predicate and the observed concrete outcome.

### Solver-Guided Mutation
At any branch site, the path constraint prefix up to that site is conjoined with the negation of the concrete branch taken. The SMT solver (Z3) attempts to solve for inputs that would flip the outcome. If the constraint set is satisfiable ($\Sigma'$ is sat), new primitive arguments $v'$ for the transaction are extracted.

### Trace-Driven Transaction Mutation
Given new input assignments, mutated transactions $T'$ are synthesized by replacing original arguments with those derived from solver outputs. These follow-up transactions are queued for subsequent dual execution runs.

## 4. Move-Specific Symbolic Semantics

Move’s features necessitate multiple symbolic semantics adjustments:
- **Type safety**: Every symbolic expression is annotated with its Move type, and resource types (e.g., Coin<T>) are filtered out of symbolic input domains.
- **Resource abilities**: Resource-type arguments are managed via the type graph rather than direct symbolic instrumentation, ensuring correct production/consumption semantics.
- **Vectors**: Move vectors are modeled concretely with symbolic elements, with all index/bound constraints encoded symbolically ($0 \leq i < n$).

Enforcement of these checks ensures that all synthesized mutations are semantically correct and pass MoveVM’s runtime validation; transactions failing type/resource checks are never proposed [2512.02918].

## 5. Constraint Management, Heuristics, and Solver Integration

To maintain efficiency and avoid solver bottlenecks:
- Local algebraic simplification (e.g., $0 + x \rightarrow x$) reduces expression complexity.
- Bound constraints are tightened (e.g., $0 \leq \alpha \leq 1000$ and $10 \leq \alpha$ becomes $10 \leq \alpha \leq 1000$).
- When mutating branches, only constraints up to the selected site are retained.
- Branch-flipping selection is random, but weighted to prioritize shallower branches and unexplored control-flow.

SMT queries are encoded in SMTLIB2 and submitted to Z3 with bounded timeouts (typically 200 ms), operating on Move-legal bit-widths (capped at 256 bits for arithmetic) [2512.02918].

## 6. Illustrative Example: Assertion Inversion

In the case of a repay<T> function asserting $paid = amount + fee$, the executor:
- Symbolically represents $amount$ and $split\_amount$ as $\alpha_1$ and $\alpha_2$
- At the assertion, records that the transaction fails when $paid \neq amount + fee$
- Inverts the assertion in the path constraint: $\Pi' = \Pi \wedge (\alpha_2 = \alpha_1 + fee)$
- Solves for inputs such that $\alpha_2 = 1.001 \cdot \alpha_1$, e.g., $\alpha_1 = 1000$, $\alpha_2 = 1001$
- Synthesizes a new transaction satisfying this relationship, exposing the assertion bug [2512.02918]

## 7. Limitations and Impact

Belobog’s concolic executor currently does not symbolically model on-chain storage beyond transaction arguments; complex stateful patterns across calls are mitigated via forking seeded on-chain objects. The system is also limited in non-linear and large-bit arithmetic, delegating those to Z3’s BV engine within capped widths. Invariant-specific oracles are not automatically synthesized; user-provided oracles and an API are available.

The concolic executor proved central in reproducing real-world exploits:
- **Cetus attack (May 2025, $200M loss)**: Solver-guided mutation solved subtle bit-vector constraints arising from overflow operations, enabling rapid exploit synthesis that random fuzzing could not reach.
- **Nemo attack (Nov 2025, $3M loss)**: The symbolic executor correctly sequenced resource-affecting calls and solved price-arithmetic mutations needed to synthesize profitable attacks [2512.02918].

Without concolic reasoning, neither type-graph nor random fuzzing approaches can meet the path constraint inversion required to discover such deep, value-dependent bugs.

---

The concolic executor in Belobog establishes an effective methodology for systematic exploration of smart contract paths under strict typing and resource regimes, enabling efficient, well-typed input synthesis and exposing vulnerabilities that evade conventional testing and fuzzing approaches [2512.02918]. The approach synthesizes coverage-centric symbolic execution principles with the Move language’s advanced type and resource model, defining an impactful paradigm for automated smart contract security validation in modern blockchain systems.

Source: https://www.emergentmind.com/topics/concolic-executor-in-belobog