Every finding that Sanctifier emits carries a stable code string. These codes appear in the coloured terminal output ofDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Centurylong/sanctifier/llms.txt
Use this file to discover all available pages before exploring further.
sanctifier analyze, in the findings[].code field of JSON reports, and as keys in the error_codes summary object. Codes are defined in sanctifier-core/src/finding_codes.rs and are guaranteed unique by a compile-time test.
The table below lists every code in the current registry. Click a row to expand the full trigger description, a vulnerable code example, and the recommended fix.
Complete Code Table
| Code | Category | Description |
|---|---|---|
S001 | authentication | Missing authentication guard in a state-mutating function |
S002 | panic_handling | panic! / unwrap / expect usage that may cause runtime aborts |
S003 | arithmetic | Unchecked arithmetic operation with overflow/underflow risk |
S004 | storage_limits | Ledger entry size exceeds or approaches the configured threshold |
S005 | storage_keys | Potential storage key collision across contract data paths |
S006 | unsafe_patterns | Potentially unsafe language or runtime pattern detected |
S007 | custom_rule | User-defined regex rule matched contract source |
S008 | events | Inconsistent topic counts or sub-optimal gas patterns in events |
S009 | logic | A function call returns a Result that is not consumed or handled |
S010 | upgrades | Potential security risk in contract upgrade or admin mechanisms |
S011 | formal_verification | Z3 formally proved a mathematical violation of an invariant |
S012 | code_hygiene | Hardcoded admin address or secret literal in an authentication context |
S013 | code_hygiene | Transfer/mint/burn missing amount > 0 or from != to validation |
S014 | code_hygiene | Deprecated soroban-sdk host function with a suggested replacement |
S015 | code_hygiene | Dead code or always-true guard condition via constant folding |
S016 | code_hygiene | Inconsistent or duplicate discriminants in #[contracterror] enum |
S017 | arithmetic | Fee/interest calculation rounds to zero for micro-amounts (fee-evasion risk) |
SANCT_UNWRAP | panic_handling | unwrap / expect / risky unwrap_or_default inside #[contractimpl] entrypoints |
SANCT_ARG_DOS | denial_of_service | Entrypoint iterates over a Vec or Map argument without a visible length cap |
Per-Code Details
S001 — Missing require_auth (authentication)
S001 — Missing require_auth (authentication)
scan_auth_gaps visitor finds every pub fn in an impl block that calls .set(), .update(), or .remove() on a storage handle but never calls require_auth or require_auth_for_args anywhere in the same function body. The heuristic inspects receiver-chain tokens for "storage", "persistent", "temporary", and "instance".Vulnerable codeenv.require_auth() (or addr.require_auth()) as the first statement of any public function that mutates state.S002 — Panic / Unwrap / Expect (panic_handling)
S002 — Panic / Unwrap / Expect (panic_handling)
scan_panics visitor walks all impl functions and flags:panic!(...)macro invocations.unwrap()method calls.expect(...)method calls
SANCT_UNWRAP code (see below) is emitted for the same patterns specifically inside #[contractimpl] entrypoints.Vulnerable codeResult and propagate errors with ?. Reserve unwrap() and expect() for tests.S003 — Arithmetic Overflow (arithmetic)
S003 — Arithmetic Overflow (arithmetic)
ArithVisitor finds bare +, -, *, +=, -=, and *= operators inside contract impl functions. One finding is emitted per (function_name, operator) pair — multiple uses of the same operator in one function produce a single diagnostic.Vulnerable codechecked_add, checked_sub, checked_mul and propagate None as a typed error.S004 — Ledger Entry Size Risk (storage_limits)
S004 — Ledger Entry Size Risk (storage_limits)
analyze_ledger_size scanner walks every #[contracttype] struct and enum, estimates the serialized size of each field using conservative type-size heuristics, and emits ApproachingLimit when the total exceeds ledger_limit × approaching_threshold (default 80% of 64,000 bytes) or ExceedsLimit when it meets or exceeds ledger_limit.Vulnerable codeS005 — Storage Key Collision (storage_keys)
S005 — Storage Key Collision (storage_keys)
StorageVisitor tracks every storage key — string literals, Symbol::new calls, symbol_short! macros, and named constants — grouped by storage type. After the full file walk, final_check() emits a collision for each key that appears in the same storage tier (instance, persistent, or temporary) more than once.Vulnerable code#[contracttype] enum as the key type so each variant is distinct at the type level:instance vs persistent vs temporary) is not flagged — those namespaces are isolated at the host level.S006 — Unsafe Patterns (unsafe_patterns)
S006 — Unsafe Patterns (unsafe_patterns)
analyze_unsafe_patterns visitor (backed by UnsafeVisitor) scans the full file AST for panic! macros, .unwrap(), and .expect() method calls, recording line numbers from proc-macro2 span locations. This overlaps with S002 but operates as a broader file-scope visitor rather than being limited to impl blocks.Fixed codeSame remediation as S002: replace unwrap/expect with ? or explicit match/if let, and replace panic! with panic_with_error! for typed contract errors.S007 — Custom Rule Match (custom_rule)
S007 — Custom Rule Match (custom_rule)
[[custom_rules]] in .sanctify.toml. Custom rules can enforce project-specific conventions that Sanctifier’s built-in detectors don’t cover.Configurationregex::Regex against each source line. Invalid regex patterns are silently skipped.S008 — Event Inconsistency (events)
S008 — Event Inconsistency (events)
scan_events scanner collects all env.events().publish(topics, data) calls and checks two conditions:- Inconsistent schema: the same event name is published with different numbers of topics in different code paths.
- Optimizable topic: a topic uses a string literal where
symbol_short!would suffice (≤9 bytes saves host gas).
symbol_short! for all topic names ≤9 bytes and keep the topic count consistent across every emit site for the same event name.S009 — Unhandled Result (logic)
S009 — Unhandled Result (logic)
scan_unhandled_results visitor finds calls in public impl functions where the called function returns a Result but the return value is neither bound to a variable, matched with ? or match, nor consumed by unwrap/expect/map/and_then.Vulnerable codeS010 — Upgrade Risk (upgrades)
S010 — Upgrade Risk (upgrades)
analyze_upgrade_patterns scanner identifies public functions whose names match upgrade/admin patterns (upgrade, set_admin, update_admin, transfer_admin, deploy, set_authorized, etc.) and flags them with a governance finding when no timelock or multi-sig check is evident in the function body.Vulnerable codeS011 — SMT Invariant Violation (formal_verification)
S011 — SMT Invariant Violation (formal_verification)
sanctifier prove when SmtProver or SmtInvariantVerifier returns ProofStatus::Violated — meaning Z3 found a concrete counterexample demonstrating that the invariant can be broken. The finding includes the counterexample variable assignments.Example outputamount <= from_balance) is added before the subtraction.S012 — Hardcoded Address (code_hygiene)
S012 — Hardcoded Address (code_hygiene)
initialize and read it back on each privileged call:S013 — Edge-Case Amount Validation (code_hygiene)
S013 — Edge-Case Amount Validation (code_hygiene)
amount > 0 guard or, for transfers, a from != to check. Missing these guards can lead to zero-amount events, self-transfer edge cases, or unexpected state in downstream logic.Vulnerable codeS014 — Deprecated SDK Function (code_hygiene)
S014 — Deprecated SDK Function (code_hygiene)
soroban-sdk host function that has been superseded by a newer, preferred API. Deprecated functions may be removed in future Stellar protocol upgrades.The finding message includes the suggested replacement. Update to the replacement to maintain forward compatibility.S015 — Dead Code / Always-True Guard (code_hygiene)
S015 — Dead Code / Always-True Guard (code_hygiene)
true or always false based on literal values visible in the same scope — for example if 1 > 0 { ... } or assert!(true). Always-true guards waste gas; always-false branches are dead code that confuses reviewers.Vulnerable codeS016 — Error Code Collision (code_hygiene)
S016 — Error Code Collision (code_hygiene)
#[contracterror] enum whose variants share the same u32 discriminant. Duplicate discriminants cause the contract ABI to map two distinct error names to the same wire value, making client-side error handling ambiguous.Vulnerable codeS017 — Fee Rounding (arithmetic)
S017 — Fee Rounding (arithmetic)
SANCT_UNWRAP — Entrypoint Unwrap (panic_handling)
SANCT_UNWRAP — Entrypoint Unwrap (panic_handling)
unwrap(), expect(..), and risky unwrap_or_default() calls inside #[contractimpl] entrypoints specifically. In a contract entrypoint, an attacker-controlled missing value can abort the whole transaction or silently turn absent financial state into a default value (e.g. returning a zero balance that was never set).Result, map missing state to a domain-specific Error, or use unwrap_or(0) only when zero is the intended contract state for all uninitialized accounts and that semantics is clearly documented:SANCT_ARG_DOS — Argument DoS (denial_of_service)
SANCT_ARG_DOS — Argument DoS (denial_of_service)
Vec or Map argument without a visible length cap. A malicious caller can pass an arbitrarily large collection, causing the transaction to consume enough instructions to hit Soroban’s per-transaction gas limit and deny service to legitimate users.Vulnerable codeWhere Codes Appear
Finding codes surface in three places:Terminal Output
sanctifier analyze prints each finding with its code, severity colour, message, and file location.JSON findings[]
findings carries a "code" string field matching one of the constants above.error_codes object
error_codes object in the JSON report maps every code to its category and description.sanctifier-core/src/finding_codes.rs and re-exported via all_finding_codes(), which powers both the JSON report table and the compile-time uniqueness test that prevents accidental duplicate codes.