Skip to content

fix(F-9): independently prove the sbtc-pool-v2 deposit-reentrancy variant - #86

Merged
mattglory merged 2 commits into
mainfrom
security-lead/f9-sbtc-pool-v2-independent-proof
Oct 5, 2026
Merged

mattglory merged 2 commits into
mainfrom
security-lead/f9-sbtc-pool-v2-independent-proof

Conversation

@unixwhisperer

Copy link
Copy Markdown
Collaborator

Summary

  • flashstack-sbtc-pool-v2 was previously only read directly and judged to share flashstack-stx-pool-v2's F-9 deposit-as-repayment vector (Flashstack-ajv.4.8), not independently simnet-proven. Its repayment path goes through a SIP-010 transfer call (asserts tx-sender == sender) rather than stx-transfer? — a materially different mechanism, worth confirming rather than assuming it carries over.
  • Adds tests/sbtc-pool-v2-deposit-reentrancy.test.ts and receiver contracts/test/test-sbtc-pool-v2-receiver-deposit-reentrant.clar (registered in Clarinet.toml), mirroring stx-pool-v2-deposit-reentrancy.test.ts's as-contract construction.
  • Updates docs/security/FINDINGS_REGISTER.md's F-9 row to record the sBTC pool as confirmed rather than "not yet independently proven."

Result

3/3 new tests pass: the loan succeeds via deposit-as-repayment; the receiver contract ends up with shares funded entirely out of the loan proceeds (attacker spends nothing beyond a fee-sized buffer) while the honest LP's value drops; a control honest-repay-by-transfer receiver gets exactly zero shares, isolating the effect to the deposit-reentrancy mechanism and ruling out a harness artifact.

Both live v2 pools remain paused=true (Matt's existing mitigation, unaffected by this PR) — this is evidence-gathering only, no contract or mitigation change.

Test plan

  • npx vitest run tests/sbtc-pool-v2-deposit-reentrancy.test.ts — 3/3 pass
  • npx vitest run (full suite) — 263 passed, 3 pre-existing skips, 0 failures, no regressions

🤖 Generated with Claude Code

…iant

flashstack-sbtc-pool-v2 was previously only read directly and judged to
share flashstack-stx-pool-v2's deposit-as-repayment vector (ajv.4.8), not
independently simnet-proven. Its repayment path goes through a SIP-010
transfer (asserts tx-sender == sender) rather than stx-transfer?, a
materially different mechanism worth confirming rather than assuming.

Adds a receiver that reenters deposit() from inside a flash-loan callback,
funded via as-contract from the loan proceeds, mirroring
stx-pool-v2-deposit-reentrancy.test.ts's construction. A control receiver
that repays by plain transfer gets zero shares, isolating the effect to the
deposit-reentrancy mechanism. FINDINGS_REGISTER.md's F-9 row updated to
match.
@vercel

vercel Bot commented Oct 4, 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 4, 2026 8:01pm UTC

Request Review

… set

test-sbtc-pool-v2-receiver-deposit-reentrant.clar is a contracts/test/ file
like its already-accepted STX sibling (test-pool-v2-receiver-deposit-reentrant.clar,
already in KNOWN_TEST_PATHS), so it shows up in what `clarinet deployments
apply --mainnet` would publish from this repo. Reviewed addition, same
category as the existing entry -- not a silent list growth.
@mattglory
mattglory merged commit e0367e0 into main Oct 5, 2026
6 of 7 checks passed
@mattglory
mattglory deleted the security-lead/f9-sbtc-pool-v2-independent-proof branch October 5, 2026 01:21

This branch was successfully deployed

1 active deployment
Preview — 13a64c6f Deployed Oct 4, 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.

2 participants