Skip to content

feat(bitflow): hardened v5 arb receiver, replacing the vulnerable v1-v4 line - #96

Open
mattglory wants to merge 1 commit into
mainfrom
bitflow-arb-receiver-v5-hardened
Open

mattglory wants to merge 1 commit into
mainfrom
bitflow-arb-receiver-v5-hardened

Conversation

@mattglory

Copy link
Copy Markdown
Owner

Summary

  • bitflow-arb-receiver / -v2/-v3/-v4 were all found vulnerable under F-10 (fix(F-10): remove 3 unrestricted-callback receivers from flashstack-stx-core #95): no contract-caller check on execute-stx-flash, repaid to a caller-supplied core instead of a hardcoded one. All removed from flashstack-stx-core's approved-receiver list.
  • Removal stopped new flash loans from reaching them, but never did the actual thing the original review table asked for: a v3-style hardened rewrite, so Bitflow arb goes from "not approved, not usable" back to "switched on."
  • bitflow-arb-receiver-v5.clar ports the already-proven alex-arb-receiver-v5 hardening pattern onto Bitflow's real swap mechanics, confirmed live against stableswap-stx-ststx-v-1-2's actual deployed interface rather than assumed: contract-caller == FLASH-CORE gate (+ defense-in-depth assert on the core parameter itself), hardcoded repay target, a required pre-set slippage floor (auto-reset after each use), a max-fee-bp guard against a fee-increase race condition, a min-profit floor, two-step ownership transfer, and exact-output capture from the swap's own return value rather than a post-swap balance read (closing the same residual-token-pollution gap ALEX v5's [M-1] fixed — confirmed Bitflow's swap-x-for-y/swap-y-for-x both return the output amount directly, so this ports cleanly).

Not included

  • Not deployed, not approved on any core. This is the contract only.
  • FINDINGS_REGISTER.md intentionally untouched — this branch is off main, which doesn't have F-10 in it yet (still on the unmerged f10-remove-vulnerable-receivers branch). Adding an entry here risked an ID collision once both merge. Reconciling the register is left for whichever branch merges second.

Test plan

  • clarinet check — clean, zero errors (one real bug caught along the way: a define-constant-bound principal silently fails Clarinet's read-only purity check inside an as-contract-wrapped call where an inline literal principal passes — same semantics, different static-analysis outcome; documented inline in the contract)
  • tests/bitflow-arb-receiver-v5-security.test.ts — 6/6 passing: direct-call rejection, rejection even via this project's own local flashstack-stx-core copy (proves the gate checks the real mainnet address, not .flashstack-stx-core sugar), all pre-flight guards, owner-gating on every admin function, zero-amount rejection on rescues, two-step ownership transfer, get-settings defaults
  • Mutation-verified: removing the contract-caller == FLASH-CORE assert was confirmed to flip the caller-gate test red (falls through to the next guard, ERR-MIN-STSTX-UNSET) rather than the test trivially passing regardless
  • Not yet tested: a full profitable-arb round-trip against live Bitflow pool liquidity — would require registering the pool/stSTX/LP token as Clarinet requirements, out of scope for this PR since every guard that matters for the F-10 fix itself runs before the swap calls are ever reached

🤖 Generated with Claude Code

bitflow-arb-receiver / -v2/-v3/-v4 were found vulnerable under F-10 (no
contract-caller check, repaid to a caller-supplied `core` instead of a
hardcoded one) and removed from flashstack-stx-core's approved-receiver
list. Removal stopped new loans reaching them, but never addressed the
actual ask: a v3-style hardened rewrite, so Bitflow arb stays usable.

v5 ports the already-proven alex-arb-receiver-v5 pattern onto Bitflow's
real swap mechanics (confirmed live against stableswap-stx-ststx-v-1-2's
actual interface, not assumed): contract-caller == FLASH-CORE gate,
hardcoded repay target, required pre-set slippage floor, max-fee-bp guard,
min-profit floor, two-step ownership, exact-output capture from the
swap's own return value rather than a balance read.

6 tests, mutation-verified (the caller-gate test was confirmed to
actually fail when the gate is removed, not just trivially pass). Not
deployed or approved on any core yet.

FINDINGS_REGISTER.md intentionally untouched here -- this branch is off
main, which doesn't have F-10 in it yet (still on the unmerged
f10-remove-vulnerable-receivers branch); reconciling that entry is left
for whichever branch merges second, to avoid an ID collision.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
web Ready Ready Preview Oct 10, 2026 8:07am UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — 3f6c4185 Deployed Oct 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant