Meteora Hooks
MAINNET
08 / Security lab

Attacked on purpose.

Stateful fuzzing, invariants and adversarial operations against the compiled programs, plus the tests behind each attack category.
Not audited. This report lists automated tests and their results. It is not an audit, and passing it does not mean the programs are free of vulnerabilities. Meteora Hooks has not had an external audit. Mainnet hook-router activation is pending.
01

Stateful fuzzing

token-wrapper + token-hooks
Seed
1
Runs × steps
8 × 40
Operations executed
320
Succeeded / refused
161 / 159
Invariant violations
none in this run

Coverage

wrap97
unwrap84
transfer63
attack:unwrap-victim12
verify_reserves12
attack:direct-execute11
attack:wrap-from-victim10
attack:direct-mint9
attack:foreign-policy9
attack:transfer-no-hook8
attack:fake-vault5

Invariants checked after every step

  1. reserves-cover-supply
  2. fee-free-underlying-is-exactly-backed
  3. wrapped-balances-sum-to-supply
  4. underlying-conserved
  5. wrapper-totals-match-supply
  6. failed-operations-change-nothing
  7. attacks-fail
  8. honest-operations-behave-as-specified

A failing sequence is shrunk to a minimal reproduction. The test suite also forges unbacked supply to prove the reserve invariant catches it.

Provenance: commit 9327d8e, generated 2026-10-20
Commit
9327d8e27103
Generated
2026-10-20T18:16:26.335Z
Runtime
LiteSVM (node, litesvm 1.6.1) with the compiled .so files
token_hooks.so sha256
969dd56de202ba3e740f6b6aa6875d43406aee7679c4b2522266b49d196b7e36
token_wrapper.so sha256
d37cdbe6acab5c349bbc42ece5b86fe37219cb73fd69d8ec2a2bfde7f401c067
anti_jit_hook.so sha256
ee6c37e94d71f2b8ebe153607ee1b0b2ee5b914e1d982b585184db56236b506d
pnpm --filter @pump-hooks/web export-data (fuzz seed 1, 8 runs × 40 steps)
02

Adversarial operations

each must fail and change nothing
wrap-from-victimwrap signed by the attacker, debiting the victim's underlying account
unwrap-victimunwrap signed by the attacker, burning the victim's wrapped tokens
fake-vaultwrap that names the attacker's own token account as the vault
direct-mintToken-2022 mint_to on the wrapped mint signed by the attacker
direct-executetoken-hooks execute called directly, outside a Token-2022 transfer
foreign-policyunwrap that passes another mint's policy account to the hook check
transfer-no-hookwrapped transfer_checked without the hook's extra accounts
03

Attack categories

15 categories
01
Missing or forged signer
An instruction acts for an account whose owner did not sign.
initialize_requires_the_upgrade_authoritycredit_operations_require_hook_authoritywrap-from-victimunwrap-victim
4 tests
02
Wrong authority
A signer that is not the configured authority changes state it does not control.
status_only_moves_forward_and_only_by_authoritybuiltins_only_from_admin_with_exact_claimsprivate_policies_only_apply_to_their_authoritydirect-mint
4 tests
03
Account substitution
A caller passes a look-alike account (vault, pool, policy, token account) in place of the bound one.
execute_rejects_protected_accounts_self_cpi_and_substitutionadapter_rejects_disabled_venues_unknown_instructions_and_substituted_accountswrong_hook_accounts_are_rejectedfake-vaultforeign-policy
5 tests
04
Forged hook invocation
A hook is called outside the operation it guards, to consume limits or fake approvals.
forged_callbacks_are_refused_by_the_hookdirect-execute
2 tests
05
Reentrancy and self-CPI
A hook or executed instruction calls back into the engine mid-operation.
hook_cannot_reenter_coreexecute_rejects_protected_accounts_self_cpi_and_substitution
2 tests
06
Hook access to user assets
A hook moves tokens or lamports that belong to the user.
hook_cannot_spend_trader_tokenssol_taken_from_the_wallet_is_measured_and_cappedexecute_blocks_token_side_channels_and_limits_tokens
3 tests
07
Unbacked minting
Wrapped or receipt tokens are created without the matching deposit.
wrapper_backs_every_wrapped_token_and_runs_the_hooksdirect-mintreserves-cover-supplyfee-free-underlying-is-exactly-backed
4 tests
08
Unauthorized withdrawal / trapped funds
Custodied funds leave without the owner, or policies trap them.
pool_policies_cannot_gate_withdrawalspause_never_blocks_withdrawalstimelocked_withdrawals_need_aged_proposals_and_cannot_be_replayedunderlying-conserved
4 tests
09
Mandatory policy removal or reset
An authority removes or weakens a mandatory entry, or resets its state, without the delay.
mandatory_policy_cannot_be_removed_without_an_aged_proposalmandatory_policy_entries_change_only_after_the_delayresubmitting_the_stack_does_not_reset_spending
3 tests
10
Hook binary substitution
A hook program is upgraded after install and keeps running with new code.
pinned_hook_stops_on_redeploypinning_requires_the_binary_the_version_describesprogram_versions_record_loader_facts
Gap: Upgradeable hooks that are not pinned run whatever is deployed; the registry records the upgrade authority so clients can show it.
3 tests
11
Replay and stale state
A signed intent, proposal or session is reused after it should expire.
deadline_and_receipt_nonce_replayproposals_go_stale_on_governance_changessessions_are_scoped_expire_and_die_with_the_epoch
3 tests
12
Slippage, sandwich and price manipulation
A trade settles at a manipulated price or worse than the user's bound.
measured_min_out_and_max_in_are_enforced_by_the_routerslot_limit_refuses_same_slot_round_tripsprice_impact_policy_reads_live_reservesprice_range_policy_reverts_swaps_that_leave_the_range
Gap: Router hooks are bypassable: the same pool remains callable directly (see max_size_caps_buys_and_venue_stays_directly_callable).
4 tests
13
Fee and transfer-fee accounting
Fees are charged above bounds, or nominal amounts are trusted instead of measured deltas.
wrapper_refuses_unsafe_underlyings_and_measures_transfer_feesafter_swap_fee_is_bounded_by_trader_limitprotocol_fee_share_is_capped_and_paid_out
3 tests
14
Initialization front-running and registry poisoning
Someone initializes a program first, squats a slug, or installs a version that does not match its claims.
initialization_cannot_be_front_runslugs_are_validated_and_uniqueinstalls_must_match_the_versionaudits_require_named_reviewers
4 tests
15
Fail-open, partial execution and compute exhaustion
An error path allows the operation, a failed transaction leaves partial state, or a stack exceeds compute.
silent_hook_is_an_error_not_an_allowcompact_policy_fits_in_a_transactioneach_measured_builtin_actually_evaluatesfailed-operations-change-nothinghonest-operations-behave-as-specifiedtransfer-no-hook
6 tests
04

Run it yourself

scripts/build_programs.sh
pumphooks security-check --runs 8 --out security-report.md
pumphooks security-check --stack <hex>      # plus diagnostics for your own stack