Skip to content

HyperSafeD/Sanctifier

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

465 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Sanctifier πŸ›‘οΈ

CI Codecov crates.io License: MIT Open in GitHub Codespaces

Sanctifier Logo

Sanctifier is a security and formal-verification suite for Stellar Soroban smart contracts. It statically analyses Rust/Soroban source code, checks for 12 classes of vulnerabilities, matches against a community-sourced vulnerability database, and optionally proves invariants with Z3.


Table of Content


πŸ“¦ Installation

From crates.io

cargo install sanctifier-cli

From source

git clone https://github.com/Jayy4rl/Sanctifier.git
cd Sanctifier/tooling/sanctifier-cli
cargo install --path .

Prerequisites: Rust 1.78+, libz3-dev and clang/libclang-dev (needed by the Z3 formal-verification backend).

# Debian / Ubuntu
sudo apt-get install libz3-dev clang libclang-dev

# macOS
brew install z3 llvm

πŸš€ Quick Start

Developer commands

Common workflows are wrapped in a root-level Makefile:

make build    # cargo build --workspace
make test     # cargo test --workspace
make lint     # cargo fmt --all --check && cargo clippy --workspace -- -D warnings
make fmt      # cargo fmt --all
make audit    # cargo audit && cargo deny check
make release  # cargo build --workspace --release
make docs     # cargo doc --workspace --no-deps --open
make clean    # cargo clean

Analyse a contract

Analyse a Soroban contract in a single command:

sanctifier analyze ./contracts/my-token
Example terminal output
⚠️ Found potential Authentication Gaps!
   -> [S001] Function: ./contracts/token-with-bugs/src/lib.rs:initialize
   -> [S001] Function: ./contracts/token-with-bugs/src/lib.rs:transfer
   -> [S001] Function: ./contracts/token-with-bugs/src/lib.rs:mint

⚠️ Found unchecked Arithmetic Operations!
   -> [S003] Op: -
      Location: ./contracts/token-with-bugs/src/lib.rs:transfer:30
   -> [S003] Op: +
      Location: ./contracts/token-with-bugs/src/lib.rs:transfer:33

⚠️ Found Unhandled Result issues!
   -> [S009] Function: transfer
      Call: Self :: balance (e . clone () , from . clone ())
      Location: ./contracts/token-with-bugs/src/lib.rs:transfer:27
      Message: Result returned from function call is not handled.

⚠️ Found SEP-41 Interface Deviations!
   -> [S012] Function: allowance
      Kind: MissingFunction
      Message: Missing SEP-41 function 'allowance'.

πŸ›‘οΈ Found 2 known vulnerability pattern(s) (DB v1.0.0)!
   ❌ [SOL-2024-002] Missing Auth on Token Transfer (CRITICAL)
   πŸ”΄ [SOL-2024-003] Unchecked Balance Underflow (HIGH)

✨ Static analysis complete.

πŸ”Ž Finding Codes

Every finding is tagged with a stable code so you can filter, suppress, or reference it in CI.

Code Category Description
S001 authentication Missing require_auth in a state-changing function
S002 panic_handling panic! / unwrap / expect usage that may abort execution
S003 arithmetic Unchecked arithmetic with overflow/underflow risk
S004 storage_limits Ledger entry size exceeds or approaches the configured threshold
S005 storage_keys Potential storage-key collision across data paths
S006 unsafe_patterns Potentially unsafe language or runtime pattern detected
S007 custom_rule User-defined rule matched contract source
S008 events Inconsistent topic counts or sub-optimal gas patterns in events
S009 logic A Result return value is not consumed or handled
S010 upgrades Security risk in contract upgrade or admin mechanisms
S011 formal_verification Z3 proved a mathematical violation of an invariant
S012 token_interface SEP-41 token interface compatibility or authorization deviation

In addition, the community vulnerability database emits SOL-2024-* codes when a known vulnerability pattern is matched. See docs/error-codes.md for full details.


πŸ›  CLI Reference

sanctifier analyze

Analyse a Soroban contract for vulnerabilities.

sanctifier analyze [OPTIONS] [PATH]
Flag Short Default Description
[PATH] β€” . Contract directory or Cargo.toml
--format <FORMAT> -f text Output format: text or json
--limit <BYTES> -l 64000 Ledger entry size limit in bytes
--vuln-db <PATH> β€” built-in Custom vulnerability database JSON
--webhook-url <URL> β€” β€” Webhook endpoint(s) for scan notifications (repeatable)
# JSON output for CI
sanctifier analyze ./contracts/my-token --format json

# Custom ledger limit and webhook
sanctifier analyze . --limit 32000 \
  --webhook-url https://hooks.slack.com/services/XXX/YYY/ZZZ

Exit code: 1 when critical or high findings are detected (useful in CI pipelines).


Webhook Integration

Use one or more --webhook-url flags to push a scan.completed notification after sanctifier analyze finishes:

sanctifier analyze ./contracts/token-with-bugs \
  --webhook-url https://discord.com/api/webhooks/XXX/YYY \
  --webhook-url https://hooks.slack.com/services/AAA/BBB/CCC

Provider-specific payloads:

Provider Payload shape
Discord { "content": "Sanctifier scan completed ..." }
Slack { "text": "Sanctifier scan completed ...", "attachments": [{ "color": "...", "fields": [...] }] }
Teams { "text": "Sanctifier scan completed ..." }
Custom webhook Raw JSON payload: event, project_path, timestamp_unix, summary

The shared payload data includes:

Field Description
event Always scan.completed
project_path Analysed path passed to sanctifier analyze
timestamp_unix Completion timestamp as UNIX seconds
summary.total_findings Total number of findings emitted
summary.has_critical Whether any critical findings were detected
summary.has_high Whether any high-severity findings were detected

Webhook delivery failures are non-fatal: Sanctifier logs a warning to stderr and still returns the analysis result.


sanctifier init

Generate a .sanctify.toml configuration file in the current directory.

sanctifier init [OPTIONS]
Flag Short Default Description
--force -f false Overwrite an existing config file

sanctifier badge

Create an SVG badge and optional Markdown snippet from a JSON scan report.

sanctifier badge [OPTIONS]
Flag Short Default Description
--report <PATH> -r sanctifier-report.json Path to a Sanctifier JSON report
--svg-output <PATH> β€” sanctifier-security.svg Output SVG file
--markdown-output <PATH> β€” β€” Output Markdown snippet file
--badge-url <URL> β€” local SVG path Public URL for the SVG
sanctifier analyze . --format json > sanctifier-report.json
sanctifier badge --report sanctifier-report.json \
  --svg-output badges/sanctifier-security.svg \
  --markdown-output badges/sanctifier-security.md

sanctifier callgraph

Generate a Graphviz DOT call graph of cross-contract calls (env.invoke_contract).

sanctifier callgraph [OPTIONS] [PATH]
Flag Short Default Description
[PATH] β€” . Contract directory, workspace, or .rs file
--output <FILE> -o callgraph.dot Output DOT file
sanctifier callgraph ./contracts/amm-pool -o amm-callgraph.dot
dot -Tpng amm-callgraph.dot -o amm-callgraph.png   # requires Graphviz

sanctifier update

Check for and download the latest Sanctifier binary from crates.io.

sanctifier update

sanctifier report

Generate a security report (writes to stdout or a file).

sanctifier report [OPTIONS]
Flag Short Default Description
--output <PATH> -o stdout Output file path

πŸ“‹ Example JSON Output

sanctifier analyze ./contracts/vulnerable-contract --format json
{
  "metadata": {
    "version": "0.1.0",
    "timestamp": "2026-03-24T12:00:00Z",
    "project_path": "./contracts/vulnerable-contract",
    "format": "sanctifier-ci-v1",
  },
  "summary": {
    "critical": 0,
    "high": 0,
    "medium": 2,
    "low": 0,
    "info": 0,
  },
  "findings": {
    "auth_gaps": [{ "code": "S001", "function": "src/lib.rs:set_admin" }],
    "panics": [
      {
        "code": "S002",
        "type": "expect",
        "location": "src/lib.rs:set_admin_secure",
      },
    ],
    "arithmetic_issues": [],
    "storage_collisions": [
      { "code": "S005", "value": "admin", "type": "storage::set (instance)" },
    ],
    "upgrade_admin_risks": [
      { "code": "S010", "category": "Governance", "function": "set_admin" },
    ],
  },
  "error_codes": [
    { "code": "S001", "category": "authentication", "description": "..." },
    "...",
  ],
  "vuln_db_matches": [],
  "schema_version": "1.0.0",
}

Note: The example above is abbreviated. See the full field reference in the JSON Schema below.


πŸ“ JSON Schema

The machine-readable contract for --format json output is published at schemas/analysis-output.json (JSON Schema draft-07).

schemas/
└── analysis-output.json   # Draft-07 schema β€” validated in CI

Downstream tools (dashboards, IDE plugins, CI integrations) can use the schema to:

  • Validate report files before processing them.
  • Generate typed bindings in any language that supports JSON Schema.
  • Detect breaking changes when the tool is upgraded.

The schema_version field in every report (e.g. "1.0.0") is bumped independently of the Sanctifier tool version whenever the output shape changes, so consumers can guard on it without coupling to the CLI release cycle.


πŸ€– GitHub Action

Sanctifier ships a composite GitHub Action (action.yml) so CI consumers can integrate with a few lines.

name: Sanctifier Scan

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read
  security-events: write

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Sanctifier
        uses: HyperSafeD/Sanctifier@main
        with:
          path: .
          format: sarif
          min-severity: high
          upload-sarif: "true"
          sarif-output: sanctifier-results.sarif

When format: sarif and upload-sarif: "true", the action uploads the SARIF file via github/codeql-action/upload-sarif@v3 so findings appear in GitHub code scanning.


πŸ“‚ Project Structure

Sanctifier/
β”œβ”€β”€ contracts/              # Soroban smart contracts (examples & test targets)
β”œβ”€β”€ frontend/               # Next.js web dashboard
β”œβ”€β”€ schemas/
β”‚   └── analysis-output.json  # JSON Schema (draft-07) for --format json output
β”œβ”€β”€ tooling/
β”‚   β”œβ”€β”€ sanctifier-cli/     # CLI binary (this is what you install)
β”‚   └── sanctifier-core/    # Static-analysis engine & Z3 backend
β”œβ”€β”€ data/
β”‚   └── vulnerability-db.json  # Community-sourced vulnerability patterns
β”œβ”€β”€ scripts/                # Deployment & CI helper scripts
└── docs/                   # Architecture decisions, guides, case studies

βš™οΈ Configuration

Run sanctifier init to generate a .sanctify.toml:

ignore_paths = ["target", ".git"]
enabled_rules = ["auth_gaps", "panics", "arithmetic", "ledger_size"]
ledger_limit = 64000
approaching_threshold = 0.8
strict_mode = false

[[custom_rules]]
name = "no_unsafe_block"
pattern = 'unsafe\s*\{'
severity = "error"

[[custom_rules]]
name = "no_mem_forget"
pattern = "std::mem::forget"
severity = "warning"

πŸ… Add a Sanctifier Badge to Your Project

Display your contract's security status directly in your repository README.

Step 1 β€” Generate the report and badge

# Produce a JSON report
sanctifier analyze . --format json > sanctifier-report.json

# Generate the SVG badge and a Markdown snippet
sanctifier badge \
  --report sanctifier-report.json \
  --svg-output .github/badges/sanctifier-security.svg \
  --markdown-output .github/badges/sanctifier-security.md \
  --badge-url "https://raw.githubusercontent.com/<owner>/<repo>/main/.github/badges/sanctifier-security.svg"

Step 2 β€” Commit the badge to your repository

git add .github/badges/sanctifier-security.svg
git commit -m "ci: add Sanctifier security badge"

Step 3 β€” Embed the badge in your README

Copy the snippet from sanctifier-security.md, or paste directly:

[![Sanctifier: Secure](https://raw.githubusercontent.com/<owner>/<repo>/main/.github/badges/sanctifier-security.svg)](https://github.com/HyperSafeD/Sanctifier)

What the badge reflects

Badge color Status Meaning
🟒 Green Secure Zero findings
🟠 Orange Warning At least one finding (high severity or any finding)
πŸ”΄ Red Critical At least one critical-severity finding

The badge is regenerated automatically whenever you re-run sanctifier badge with an updated report. Add it to your CI pipeline so the badge always reflects the latest scan result.


πŸ“š Documentation

Document Description
Getting Started First-run walkthrough
Error Codes Full finding-code reference
Runtime Guards Integration Adding runtime guards to your contract
CI/CD Setup GitHub Actions integration
Soroban Deployment Deploy guard contracts to testnet
Contributing Analysis Rules Writing custom analysis rules
Case Studies Benchmark against official Soroban examples
Architecture Decisions ADRs for design choices

🀝 Contributing

We welcome contributions from the Stellar community! Please see the Contributing Guide for details on setting up your development environment, running tests, and submitting pull requests.


πŸ“„ License

MIT

About

Stellar Soroban Security & Formal Verification Suite- Static Analysis, Runtime Guards, and Formal Verification Bridge.

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors