A real Sniff run on example_vault, a benchmark program Verafy wrote with two deliberate bugs. Its source is in the Fuzzy repository.

20Broken

example_vault scored 20

Fuzzy tested it to a depth of 55, and a proven critical finding caps the score at 20. Fix it and run again to lift the cap.

Sniff · Nov 9, 2026 · 185 transactions · sha256 6abeccc8b778…

Depth 55 of 100

How hard Fuzzy tried
Branch coverage0 / 40
Not measured in this engine version
Instruction coverage20 / 20
3 of 3 instructions driven to both success and failure
Attack classes tried20 / 20
7 of 7 classes that apply to this program
Real state5 / 10
Synthetic accounts built from the IDL
Effort10 / 10
Share of the planned run completed

What sets the cap

CRITICAL2 proven, this sets the capcap 20
HIGHNone provencap 45
MEDIUMNone provencap 70
LOWNone provencap 90

Score is the lower of Depth and the cap from the worst proven finding. Leads never count.

2 proven findings

CRITICAL

Anyone can re-run initialize, take over the account, then withdraw its funds

F1

initialize does not check that the account is new. The attacker ran it again on an account the owner had already set up and wrote their own key in as the authority, then called withdraw and took 1 SOL.

The attack, in order

  1. initialize by the owner, setup
  2. initialize by the attacker
  3. withdraw (1000000000) by the attacker
AccountBeforeAfter
Program account (vault)5.0009 SOL4.0009 SOL
Attacker10 SOL10 SOL
Attacker's wallet0 SOL1 SOL

Fix: Refuse to initialize an account that already holds data (check the discriminator, or use Anchor's init constraint).

The attack transaction and logs
ARiCubNQJsGdQlDDTx16KsrdEVEEUSMZJNmfe/LSG0tntfdOCOgCH3bV3CUXzi3uTww+mdcw3TXy1Y7VbR4auACAAQABBOqKZtl84I9L99CyFvDYIhzmDShDpy9s5UcIVlKZMWI1T41G83VI77KZ0wtB3dG5tmt7MKYKxAZlP4SYT89XHvOftmPx7nJieqkZ1TNn/H514K0aP5DN5dqI6Ku5BakqLZ0Sc1JsvGIKVYoOhjU5eSvq/MzIHLz9o0cK35h8zmT3JMVFG1a5xTCX5HoyCv0ySid+9E/Ili4eePBCdTeejDwBAwMBAAIQtxJGnJRtoSIAypo7AAAAAAA=
Program Ba9KvV1PMnLu37UT9R3XVQ26AYyvQ6kq5j83otRAkkyt invoke [1]
Program Ba9KvV1PMnLu37UT9R3XVQ26AYyvQ6kq5j83otRAkkyt consumed 794 of 200000 compute units
Program Ba9KvV1PMnLu37UT9R3XVQ26AYyvQ6kq5j83otRAkkyt success

Replay it locally with the report JSON: clone github.com/Verafyai/fuzzy, then npm run fuzzy -- replay report.json F1 --program your_program.so --idl idl.json

CRITICAL

Anyone can call withdraw without authority's signature and take funds

F2

withdraw never checks that authority signed. The attacker named the authority without their signature and the transaction succeeded, moving 1 SOL to the attacker.

The attack, in order

  1. initialize by the owner, setup
  2. withdraw (1000000000) by the attacker
AccountBeforeAfter
Program account (vault)5.0009 SOL4.0009 SOL
Attacker's wallet0 SOL1 SOL
Attacker10 SOL10 SOL

Fix: Require authority to be a signer (in Anchor, Signer<'info>).

The attack transaction and logs
AdvYO4hoYF2AOTRtuHNOVw/WH/L+qZ8Hao9TPDbc9OMh13lcjJ9K6SRAUnL62J+Dm2OMvtxysA60UxVZLl24LgaAAQACBeqKZtl84I9L99CyFvDYIhzmDShDpy9s5UcIVlKZMWI1T41G83VI77KZ0wtB3dG5tmt7MKYKxAZlP4SYT89XHvOftmPx7nJieqkZ1TNn/H514K0aP5DN5dqI6Ku5BakqLZ0Sc1JsvGIKVYoOhjU5eSvq/MzIHLz9o0cK35h8zmT3q41TqsavOGFmzDK4fIzJMBU1oNdNyR432ZIOhpYW4o8ypyqAQ/TOXJYplK4TfTUKC/8wMulxnikjY4y8ar/MnwEDAwEEAhC3EkaclG2hIgDKmjsAAAAAAA==
Program Ba9KvV1PMnLu37UT9R3XVQ26AYyvQ6kq5j83otRAkkyt invoke [1]
Program Ba9KvV1PMnLu37UT9R3XVQ26AYyvQ6kq5j83otRAkkyt consumed 796 of 200000 compute units
Program Ba9KvV1PMnLu37UT9R3XVQ26AYyvQ6kq5j83otRAkkyt success

Replay it locally with the report JSON: clone github.com/Verafyai/fuzzy, then npm run fuzzy -- replay report.json F2 --program your_program.so --idl idl.json

1 lead checked and not counted
  • ping accepts a fake vault. It accepted an account the program does not own, but changed nothing, so it is not counted.

Attack classes

Missing signer checkbroke it
Missing owner checkheld
Account substitutionheld
PDA seed collisiondoes not apply
Arithmetic overflowheld
Close, then reusedoes not apply
Unchecked CPI targetdoes not apply
Unchecked mint or authoritydoes not apply
Lamport drainingheld
Reinitializationbroke it
Price manipulationdoes not apply
Compute exhaustionheld

About this run

  • Every finding was reproduced in LiteSVM with the transaction attached. Leads were tried and did not break anything; they never count toward the score.
  • Branch coverage is not measured yet, so it adds 0 of 40 to Depth. With synthetic accounts, that caps any score from this engine version at 55.
  • Accounts are synthetic, built from the IDL.
  • Theft is measured in SOL. Token balances are not yet part of the proof, so token-only exploits show up as leads at most.