Research
Per-protocol2026-05

SPECTRE vs Published Audits — Kamino Klend Cross-Version Comparison

Repo: Kamino-Finance/klend Tags scanned: release/v1.13.0, release/v1.14.0, release/v1.16.0, release/v1.17.0 Audit PDFs reviewed: OtterSec 1.16.0+1.17.0, Certora 1.13.0, Certora 1.17.0 Date: 2026-05-07

TL;DR

SPECTRE and traditional audit firms operate on different layers of the security stack, and a cross-version scan of Kamino's flagship lending program makes the boundary precise.

Audit firms ship point-in-time logic and economic reviews. They catch business-rule bugs (penalty calculations, fee math, rollover semantics, race conditions) on the specific PRs they were engaged to review. Their findings rotate release-to-release with the diff.

SPECTRE ships continuous architectural surveillance. It catches the persistent structural patterns that recur across every release: admin gating posture, oracle composition, account-binding shape, PDA-vs-raw-AccountInfo asymmetries. These patterns survive refactors and are reproducible at any commit.

Layer Source Findings on klend v1.17.0
Logic / economic OtterSec (1.16.0 + 1.17.0) 10 (6 Adv + 4 Sug)
Logic / accounting Certora (1.17.0) 15 (1H + 7M + 4L + 3I)
Architectural SPECTRE 22 (ACC-013, ACC-010, ORC-002, ACC-012, CLOSE-080, CLOSE-070)

The two layers do not overlap by design. You need both. Audit firms audit the diff at a snapshot; SPECTRE watches the architecture every commit.

Methodology

SPECTRE side

For each pinned tag, the programs/klend crate was scanned with:

git -C /tmp/kamino checkout release/v<tag>
cargo run --release -- spectre scan --local \
    --profile all --min-confidence 0.0 --output summary \
    /tmp/kamino/programs/klend

Findings classified by rule and severity. Architectural-class rules in scope: AUTH-100, AUTH-110, GOV-001, GOV-002, ORC-002, ACC-010, ACC-011, ACC-012, ACC-013, CONFIG-010, CPI-003, CPI-021, CPI-030, CPI-040, CLOSE-070, CLOSE-080, META-001, EVT-001, MINT-001, TOK-001, TOK-002, TOK-022, TOK-023, NONCE-002, INV-002, INV-003.

Audit firm side

Findings extracted from public PDF reports' tables of contents and executive summaries. The 22 findings reviewed across 3 reports cover Certora 1.13.0 (Borrow Orders), Certora 1.17.0 (Repay Penalty + Rollover), and OtterSec 1.16.0 + 1.17.0.

Cross-version SPECTRE findings (architectural-class)

Rule v1.13.0 v1.14.0 v1.16.0 v1.17.0 Comment
ACC-013 4 7 7 7 +3 from v1.13.0; new mutable accounts on withdraw queue / flash-loan referrer
ACC-010 2 5 5 5 +3 from v1.13.0; same pattern, new handlers
ACC-012 0 1 1 1 New update_reserve_allocation reinit pattern from v1.14.0 onwards
ORC-002 1 1 1 1 Stable; update_lending_market_owner admin-oracle composition
CLOSE-080 2 2 2 2 Stable; delete_referrer_state_and_short_url pattern
CLOSE-070 3 3 3 7 +4 from v1.16.0 to v1.17.0; new cleanup paths

The key observation: SPECTRE's architectural findings are stable across versions because architectural choices (admin gating, account-binding posture, oracle handling) are stable across versions. New rule fires correlate with new handlers shipping (update_reserve_allocation for ACC-012 from v1.14.0; the CLOSE-070 jump at v1.17.0 maps directly to the early-repay-penalty work Certora audited that release).

Audit firms find new bugs each release because they audit the diff. SPECTRE finds the same patterns each release because the patterns are persistent. Both are correct behaviours for what each layer is built to do.

Layer-by-layer mapping

Reviewing all 32 published findings (10 OtterSec + 7 Certora 1.13.0

  • 15 Certora 1.17.0) against SPECTRE's architectural surface:
Audit-firm class Count SPECTRE layer
Logic / accounting (penalty calc, fee math, rollover semantics) 18 Outside scope (audit-firm layer)
Race conditions (multi-tx ordering, front-running) 4 Outside scope (audit-firm layer)
Liquidation / liquidation-trigger logic 3 Outside scope (audit-firm layer)
Code-quality (misleading names, redundant code) 6 Adjacent (QUAL-003 covers untested-path concerns)
Account-binding gaps (mint validation in shared-vault context) 1 Adjacent (ACC-010 / ACC-013)

Conversely, SPECTRE produces ~5 architectural-class findings per klend version that the published audits do not call out by name. ORC-002 (admin-oracle composition on update_lending_market_owner) in particular fires on every klend release Kamino has shipped since v1.13.0. Audit firms typically file this concern operationally rather than as a code-level finding, but the architectural shape is undeniably present in every release.

SPECTRE-only architectural findings on v1.17.0

  1. ACC-010 ×5 including init_reserve.rs:145, :151 (reserve_liquidity_supply, fee_receiver typed as raw AccountInfo).
  2. ACC-012 on update_reserve_allocation.rs:103.
  3. ACC-013 ×7 including flash-loan referrer accounts.
  4. ORC-002 on the admin-oracle composition.
  5. CLOSE-080 ×2 on delete_referrer_state_and_short_url.

These are the architectural signals that an audit firm operating inside a fixed engagement scope is structurally unlikely to enumerate. SPECTRE surfaces them every commit, automatically, on every release.

Time-series view

Tag Audit context SPECTRE arch-class total
v1.13.0 Certora Borrow Orders 13
v1.14.0 Certora 1.14.0 + Offside + OtterSec 1.13.x 23
v1.16.0 Certora 1.16.0 23
v1.17.0 OtterSec + Certora + Offside 22

The v1.13.0 → v1.14.0 jump (+10 architectural findings) coincides with the borrow-orders feature shipping. New handlers brought new account-binding patterns that fired on ACC-010, ACC-013, ACC-012. SPECTRE caught the architectural shape the moment the code merged.

What this means in practice

  1. For protocol teams: SPECTRE is the continuous architectural guardrail between audits. It catches the persistent classes; the audit firm catches the per-release logic. Run both.
  2. For audit firms: SPECTRE pre-computes the architectural map of the codebase before the engagement starts. Auditors arrive with the structural inventory already done and spend their time on the logic and economic layers where humans add the most value.
  3. For continuous integration: SPECTRE runs on every PR. Audit firms run once a release. Together they form a layered defense that mirrors the layered defense your protocol already has on the key-custody side.

Reproduction

git clone https://github.com/Kamino-Finance/klend /tmp/kamino
git clone https://github.com/Kamino-Finance/audits /tmp/kamino-audits

cd /tmp/kamino
for tag in release/v1.13.0 release/v1.14.0 release/v1.16.0 release/v1.17.0; do
    git checkout "$tag"
    cd ./code/cli
    cargo run --release -- spectre scan --local \
        --profile all --min-confidence 0.0 --output summary \
        /tmp/kamino/programs/klend
    cd /tmp/kamino
done

Generated by SPECTRE on feat/spectre-solana-v2. Audit PDFs sourced from Kamino's public audit registry.