""" VulnScout — Gradio app (Hugging Face Space front-end). Paste a Solidity contract/function → VulnScout encodes it on a **Modal GPU** with the SCAR sparse retriever and surfaces the most similar *known-vulnerable* code, each with the real auditor finding behind it. Every audit is live Modal inference (the judged artifact). Requires (as Space secrets): MODAL_TOKEN_ID, MODAL_TOKEN_SECRET → so this Space can call the deployed `vulnscout` Modal app. Without them, the UI loads in a clearly-labelled demo fallback instead of crashing. """ import os import gradio as gr MODAL_APP = "vulnscout" MODAL_CLS = "VulnScoutEngine" # --- Lazy Modal engine handle (cached) --------------------------------------- _engine = None _engine_err = None def _get_engine(): global _engine, _engine_err if _engine is not None or _engine_err is not None: return _engine try: import modal Engine = modal.Cls.from_name(MODAL_APP, MODAL_CLS) _engine = Engine() except Exception as e: # missing tokens, app not deployed, etc. — degrade, don't crash _engine_err = str(e) return _engine SEVERITY_COLORS = { "critical": "#b3001b", "high": "#d7263d", "medium": "#e08a00", "low": "#3a7ca5", "informational": "#6c757d", "info": "#6c757d", } def _severity_of(finding: str) -> str: head = (finding or "").strip().lower() for sev in ("critical", "high", "medium", "low", "informational", "info"): if head.startswith(sev) or f"severity: {sev}" in head: return sev return "info" def _render(out: dict) -> str: if not out or "error" in out: return f"

⚠️ {out.get('error','no response') if out else 'no response'}

" m = (f"
" f"⚡ live on Modal {out['gpu']} · encode {out['encode_ms']}ms · " f"retrieve {out['retrieve_ms']}ms · " f"this audit ≈ ${out['est_cost_usd']:.6f} · " f"index = {out['n_index']:,} known vulns · " f"{out['n_active']} sparse features active
") cards = [] for i, r in enumerate(out.get("results", []), 1): sev = _severity_of(r["finding"]) color = SEVERITY_COLORS.get(sev, "#6c757d") code = r["code"] if len(r["code"]) <= 1100 else r["code"][:1100] + "\n… (truncated)" cards.append( f"
" f"
" f"" f"{sev}" f"match #{i} · " f"similarity {r['score']:.3f} · source: {r['source']}
" f"
{_esc(r['finding'])}
" f"
{_esc(code)}
" f"
" ) if not cards: cards = ["

No similar known vulnerabilities found.

"] feats = out.get("active_features", []) feat_html = "" if feats: chips = " ".join( f"#{f['feature']} · {f['weight']:.2f}" for f in feats) feat_html = (f"
🔍 Why these matches — top sparse SAE features that fired " f"(interpretable signal)
{chips}
") return m + "".join(cards) + feat_html def _esc(s: str) -> str: return (s.replace("&", "&").replace("<", "<").replace(">", ">")) WAKING = ("
Waking the Modal GPU… the first audit after idle " "spins up an A10G from scale-to-zero (~30s). After that, audits are ~0.5s. " "Encoding your contract live on Modal…
") def audit(contract: str, top_k: int): engine = _get_engine() if engine is None: yield ("
" "⚠️ Modal backend not connected. Set MODAL_TOKEN_ID and " "MODAL_TOKEN_SECRET as Space secrets and deploy " "modal_app.py. See the demo video in the README for a live run." f"
({_engine_err})
") return if not (contract or "").strip(): yield "

Paste a Solidity contract or function to audit.

" return yield WAKING try: out = engine.audit.remote(contract, int(top_k)) except Exception as e: yield f"

⚠️ Modal call failed: {_esc(str(e))}

" return yield _render(out) EXAMPLES = [ ["""// Arbitrary delegatecall: attacker-controlled target runs in this contract's context function execute(address target, bytes calldata data) external { (bool ok, ) = target.delegatecall(data); // <-- no access control / allowlist require(ok, "call failed"); }""", 5], ["""// Unchecked return value of a low-level transfer function pay(address payable to, uint256 amt) external { to.send(amt); // <-- return value ignored }""", 5], ["""// Reentrancy: external call before state update function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount, "insufficient"); (bool ok, ) = msg.sender.call{value: amount}(""); require(ok, "transfer failed"); balances[msg.sender] -= amount; // <-- updated AFTER the external call }""", 5], ] HERO = """
Build Small  ·  powered by Modal
🛡️ VulnScout
Sparse, interpretable vulnerability precedent search for Solidity. Paste a contract — get the closest known-exploited code and the auditor's finding behind it, encoded live on a Modal GPU.
""" STATS = """
7,552
known vulns indexed
1.5B
params · laptop-class
~10ms
sparse retrieval
$0.0002
per live audit
""" MODAL_CARD = """
⚡ Modal, three ways
🏋️ Trained on Modal H100s · ~$280
📦 Indexed the corpus on Modal · Batch
This audit runs on Modal · live
""" EMPTY = """
🔍
Paste a Solidity contract or pick an example, then Scout for vulnerabilities.
""" CSS = """ .gradio-container {max-width: 1100px !important; margin: 0 auto !important;} footer {display: none !important;} .vs-stat {background:#0e1420; border:1px solid #1e2737; border-radius:12px; padding:10px 18px; min-width:130px; text-align:center;} .vs-num {font-size:21px; font-weight:800; color:#e2e8f0; font-family:'JetBrains Mono',ui-monospace,monospace;} .vs-lbl {font-size:11px; color:#7c8aa0; margin-top:3px; letter-spacing:.02em;} .scout-btn, .scout-btn button {width:100% !important; font-size:16px !important; font-weight:700 !important; letter-spacing:.01em; padding:14px 16px !important; box-shadow:0 8px 26px rgba(34,211,238,.22) !important;} .code-card .cm-editor, .code-card textarea {font-family:'JetBrains Mono',ui-monospace,monospace !important; font-size:13px !important;} .gradio-container thead th {background:#0e1420 !important; color:#cbd5e1 !important; border-color:#1e2737 !important;} .gradio-container tbody td {background:#0c1018 !important; color:#c0ccdb !important; border-color:#1b2230 !important;} .gradio-container tbody tr:hover td {background:#11161f !important;} """ theme = gr.themes.Base( primary_hue=gr.themes.colors.cyan, secondary_hue=gr.themes.colors.indigo, neutral_hue=gr.themes.colors.slate, font=[gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"], font_mono=[gr.themes.GoogleFont("JetBrains Mono"), "ui-monospace", "monospace"], ).set( body_background_fill="#080b11", body_text_color="#cbd5e1", block_background_fill="#0c1018", block_border_color="#1b2230", block_label_text_color="#8a97ad", input_background_fill="#0a0e15", button_primary_background_fill="linear-gradient(90deg,#22d3ee,#6366f1)", button_primary_background_fill_hover="linear-gradient(90deg,#3edcf5,#7c7ff5)", button_primary_text_color="#06121a", slider_color="#22d3ee", ) with gr.Blocks(title="VulnScout — Solidity vulnerability scout", css=CSS, theme=theme) as demo: gr.HTML(HERO) gr.HTML(STATS) with gr.Row(): with gr.Column(scale=3): inp = gr.Code(label="Solidity contract / function", language=None, lines=16, elem_classes="code-card") with gr.Column(scale=2): top_k = gr.Slider(1, 10, value=5, step=1, label="Matches to return") btn = gr.Button("🔎 Scout for vulnerabilities", variant="primary", elem_classes="scout-btn") gr.HTML(MODAL_CARD) out = gr.HTML(EMPTY) gr.HTML("
⚡ Try an example
") gr.Examples(examples=EXAMPLES, inputs=[inp, top_k]) gr.HTML("
" "VulnScout finds precedent — it does not replace a professional audit. " "· Built on SCAR · Compute by Modal
") btn.click(audit, inputs=[inp, top_k], outputs=out) if __name__ == "__main__": demo.launch()