1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//! Soroban WASM smart contract decompiler.
//!
//! This crate reconstructs idiomatic Rust source code from compiled Soroban
//! WASM binaries. It combines the contract specification metadata embedded in
//! the WASM custom sections with bytecode-level stack simulation to produce
//! output that closely resembles the original contract source, including type
//! definitions, function signatures, storage operations, authentication calls,
//! and cross-contract invocations.
//!
//! # Quick start
//!
//! The simplest way to use the crate is through the top-level [`decompile`]
//! function, which runs the full pipeline and returns formatted Rust source:
//!
//! ```no_run
//! use soroban_decompiler::{decompile, DecompileOptions};
//!
//! let wasm = std::fs::read("contract.wasm").unwrap();
//! let options = DecompileOptions { signatures_only: false };
//! let source = decompile(&wasm, &options).unwrap();
//! println!("{source}");
//! ```
//!
//! # Architecture
//!
//! The decompilation pipeline runs in four stages. Each stage is also
//! available as a standalone entry point for tools that need intermediate
//! results.
//!
//! 1. **Spec extraction** ([`spec_extract`]) -- reads `contractspecv0` custom
//! sections to recover struct definitions, enum variants, error codes,
//! event schemas, and function signatures with fully typed and named
//! parameters. Entry point: [`extract_spec`].
//!
//! 2. **WASM analysis** ([`wasm_analysis`]) -- parses the binary with
//! `walrus`, traces through Soroban dispatcher chains, and simulates the
//! stack for each implementation function. The simulator tracks values
//! through locals, memory stores, function calls, and control flow
//! branches, resolving host function call arguments back to their origins
//! (parameters, constants, or earlier call results). Callee memory writes
//! are propagated to the caller so that helper functions that store through
//! pointer parameters have their results visible in the calling function.
//! Entry point: [`analyze`].
//!
//! 3. **Pattern recognition** ([`pattern_recognizer`]) -- maps host call
//! sequences to high-level Soroban SDK operations. For example, a
//! `symbol_new_from_linear_memory` followed by `get_contract_data` becomes
//! `env.storage().instance().get(symbol_short!("KEY"))`. This stage also
//! resolves struct field accesses through map unpack operations, detects
//! i128 round-trips, strips Soroban Val encoding boilerplate, and runs
//! dead variable elimination and common subexpression elimination. The
//! output is a typed intermediate representation defined in [`ir`].
//!
//! 4. **Code generation** ([`codegen`]) -- walks the IR and emits Rust token
//! streams using `syn` and `quote`, then formats the result with
//! `prettyplease`. Reconstructs `#[contracttype]` definitions,
//! `#[contracterror]` error enums, `#[contractimpl]` function bodies, and
//! the top-level `#[contract]` struct with appropriate `use` imports.
use Result;
use ScSpecEntry;
/// Options controlling the decompilation process.
///
/// Pass this to [`decompile`] to configure which parts of the pipeline run.
/// Extract contract spec entries from a compiled Soroban WASM binary.
///
/// Reads the `contractspecv0` custom section and deserializes it into a list
/// of [`ScSpecEntry`] values covering struct definitions, enum variants,
/// error codes, event schemas, and function signatures.
///
/// This is the first stage of the decompilation pipeline and can be called
/// independently when only the contract metadata is needed.
///
/// # Errors
///
/// Returns an error if the WASM binary does not contain a valid
/// `contractspecv0` section or if the XDR deserialization fails.
/// Resolve all host function imports in a WASM binary.
///
/// Iterates the WASM import table and matches each function import against
/// the bundled Soroban host function database ([`host_functions`]). Returns
/// one [`wasm_imports::ResolvedImport`] per import, with semantic names
/// filled in for recognized host functions and `None` for unrecognized ones.
///
/// # Errors
///
/// Returns an error if the WASM binary cannot be parsed.
/// Analyze WASM function bodies, resolving exports and host calls.
///
/// Parses the WASM binary, builds the host function import mapping, and
/// returns an [`wasm_analysis::AnalyzedModule`] that provides per-function
/// analysis including dispatcher tracing and stack simulation.
///
/// # Errors
///
/// Returns an error if `walrus` cannot parse the WASM binary.
/// Decompile a Soroban WASM binary into formatted Rust source code.
///
/// Runs the full four-stage pipeline (spec extraction, WASM analysis,
/// pattern recognition, code generation) and returns the result as a
/// `prettyplease`-formatted Rust source string.
///
/// When [`DecompileOptions::signatures_only`] is `true`, skips the analysis
/// and pattern recognition stages entirely, producing only type definitions
/// and function stubs with `todo!()` bodies.
///
/// # Errors
///
/// Returns an error if spec extraction fails, the WASM binary cannot be
/// parsed, or the generated token stream is not valid Rust syntax.