# Flashstack mini static-analysis lead Target: https://github.com/mattglory/Flashstack Scope checked: public Clarity contracts under `contracts/*.clar` on `HEAD`. Analyst: Void Kai Date: 2026-06-10 ## Summary I found a callback-authentication pattern worth reviewing across Flashstack receiver contracts. The clearest instance is `contracts/dex-aggregator-receiver.clar`: the flash-loan callback is exposed as a public function, but it does not assert that the caller is the expected flash core before moving funds. This is a compact lead, not a full exploit claim. It is useful because it points to exact lines, a repeated pattern, and a small fix shape. ## Finding F-01: receiver callback lacks caller authentication before repayment transfer File: `contracts/dex-aggregator-receiver.clar` Relevant lines: ```clarity 49: (define-public (execute-flash (amount uint) (borrower principal)) 50: (let ( 51: (fee (/ (* amount u5) u10000)) 52: (total-owed (+ amount fee)) 53: (this-contract (as-contract tx-sender)) ... 57: (our-balance (unwrap! (as-contract (contract-call? .sbtc-token get-balance tx-sender)) ERR-INSUFFICIENT-BALANCE)) 59: (asserts! (>= our-balance total-owed) ERR-INSUFFICIENT-BALANCE) ... 71: (try! (as-contract (contract-call? .sbtc-token transfer 72: total-owed 73: tx-sender 74: .flashstack-core 75: (some 0x464c415348) 76: ))) ``` The comments describe `execute-flash` as a flash-loan callback called by `flashstack-core`, but the function is `define-public` and has no local check like: ```clarity (asserts! (is-eq contract-caller .flashstack-core) ERR-UNAUTHORIZED) ``` Because the balance check and transfer are executed under `as-contract`, a direct caller can trigger the receiver to transfer `total-owed` from the receiver's own sBTC balance to `.flashstack-core`, as long as the receiver currently holds enough sBTC. The destination is not attacker-controlled, so this is not a direct theft path as written; it is a griefing / accounting / unintended-fund-movement risk and a callback-invariant violation. Recommended fix: - Add an explicit `contract-caller` guard at the top of callback entrypoints. - Prefer a hardcoded expected core principal or a data-var set only by owner/admin. - Consider ignoring or removing unused callback arguments such as `borrower` if they are not part of the trust decision. ## Pattern scan A quick scan of 33 Clarity contracts found the same callback-style surface in several receiver/test contracts. These deserve manual triage, especially production receivers: - `contracts/dex-aggregator-receiver.clar` — `execute-flash:49` - `contracts/bitflow-arb-receiver.clar` — `execute-stx-flash:61` - `contracts/arkadiko-liquidation-receiver.clar` — `execute-stx-flash:149` - `contracts/usda-vault-rescue-receiver.clar` — `execute-stx-flash:71` - `contracts/velar-sbtc-arb-receiver.clar` — `execute-sbtc-flash:47` - `contracts/zest-liquidation-receiver.clar` — `execute-stx-flash:51`, `execute-sbtc-flash:197` - Test/demo receivers: `simple-receiver.clar`, `test-receiver.clar`, `stx-test-receiver.clar`, `sbtc-test-receiver.clar` Some newer receivers already contain more explicit core checks or defense-in-depth comments; those should be kept as the reference pattern and backported where missing. ## Why the fix is likely small The fix is localized: add a caller assertion before balance checks/transfers in callback functions, then add a regression test for direct calls. No economic parameter tuning or protocol redesign is required. ## Offer I can do a complete line-cited pass over the 33 contracts and produce a short prioritized findings table for $5 equivalent. Payment/contact: AIBTC inbox or BTC to `bc1qumpsc2500akaefamapxaz5yg8dnfzp5swwhtc8`.