Files
pumpfun-bonkfun-bot_github/docs/regression-tests.md
T
b7aae5e333 chore(monitoring,platforms,tools): retire the pumpportal listener (#232)
* chore(monitoring,platforms,tools): retire the pumpportal listener

Remove the third-party feed from the bot, the cookbook and the listener
race. It sampled rather than covered the chain, and was the one listener
that could never set state_from_event, so every buy paid the pre-buy
curve read.

Rescope the two buy-path verifiers that used it as a stand-in for a
TokenInfo without state_from_event.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* style(trading): rewrap a docstring paragraph

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-26 08:47:31 +02:00

5.3 KiB

Regression verifiers

The verifiers

Every fix ships with an offline verifier under tests/regression/. Each script's docstring carries the bug it guards and the checks it runs — read that before touching the code it covers, and run the ones your change reaches. None move funds. uv run tests/regression/run_all.py runs the whole set, or name individual scripts for a subset.

Script Checks
verify_v2_account_layout.py buy_v2/sell_v2 account layouts, PDA/ATA derivations, encoding — against idl/pump_fun_idl.json
verify_curve_account_sizes.py 125/151/256-byte curves all decode, and nothing filters on account length
verify_create_v2_optional_args.py omitted trailing option-typed create_v2 args decode as unset; mandatory args still fail
verify_transaction_v1.py every reader asks maxSupportedTransactionVersion: 1; a v1 create_v2 is detected from logs alone with the envelope unreadable, and from the envelope alone with the logs stripped; the same two routes over geyser, plus the inline v1 budget
verify_shreds_listener.py pre-execution creates decode from the instruction alone: user at create_v2 account 5, a holder-reward creator derived as PDA(["holder-rewards", mint]), truncated trailing args decoding as not-holder-reward, lookup-table accounts resolved, and nothing reading a meta the stream has no field for
verify_block_null_guard.py a blockSubscribe frame with value.block: null is skipped, not logged as an error
verify_ping_loop_close_is_quiet.py a WebSocket closing normally ends the ping loop quietly in every listener, while an unexpected failure is still logged
verify_listener_cancellation.py a cancelled WebSocket listener stops, even when websockets reports cancellation as AssertionError
verify_create_log_gate.py the create marker is matched as a whole log line, so a foreign Create* instruction is not a coin and a real create sharing its transaction with one is still detected
verify_extreme_fast_zero_rpc.py zero RPC calls between detection and submission for CreateEvent-sourced tokens
verify_curve_refresh_buy_path.py a TokenInfo without state_from_event refreshes first: an unreadable curve skips the buy, and curve + mint are read in one slot-consistent batch that corrects the token program
verify_cleanup_survives_shutdown.py shutdown cleanup runs to completion through the cancellation that triggered it, bounded, and a cleanup that hangs or raises still lets the process exit
verify_token_queue_shutdown.py cancelling the token queue processor ends it without raising, and task_done() stays balanced on the paths that took an item
verify_buy_result_not_lost.py a landed buy is never reported failed, and a reverted one never reported landed
verify_tx_status_checks.py every path reads meta.err; --live replays known reverted signatures
verify_tp_sl_exit_price.py the tp/sl exit prices off the trigger price, and a reverted sell is retried, bounded
verify_time_based_exit_retry.py the default time_based exit retries a reverted sell instead of stranding the position
verify_time_exit_without_price.py max_hold_time still fires when every price read fails
verify_exit_sell_confirmation.py an exit sell is retried only when retrying is provably safe
verify_rpc_deadline.py post_rpc bounds wall time, not just attempts (virtual clock)
verify_quote_decimals_resolved.py no trade path prices a coin before resolving its quote mint's decimals; nothing in cookbook/ or src/ falls back to a literal decimal count; both unit helpers raise for an unresolved mint; the two pre-seeded quote tables carry the same mints; the buy clears its quote gate before it sizes
verify_migration_event_discriminator.py the migration decoder rejects any payload that is not the wrapper program's CreatePoolEvent, including a foreign one long enough for the schema
verify_cookbook_arguments.py every cookbook script takes its input as a command-line argument
verify_documentation_links.py no known-dead URL is back; --live fetches every one and fails on 4xx/5xx
verify_no_rpc_credentials_logged.py credentials masked in every log record, including a URL passed as a non-str argument, and every site that installs a root handler installs the redaction first
verify_pumpfun_prices_without_hardcoded_sol_unit.py nothing in core/, trading/ or platforms/pumpfun/ scales an amount by LAMPORTS_PER_SOL; the letsbonk sites left out of scope are still the documented ones
verify_pumpswap_account_layout.py pump-amm's pool-v2 account is gated on coin_creator, the buyback pair stays last, and base-token decimals are resolved rather than assumed; --live re-reads the authorized recipients from GlobalConfig

Two mainnet simulations, also no funds moved:

uv run tools/simulate_v2_trades.py <MINT>   # buy_v2/sell_v2 for one coin, reports CU
uv run tools/simulate_bot_buy_path.py       # the bot's whole buy path, fresh coin

After any pump.fun program upgrade run verify_v2_account_layout, verify_curve_account_sizes and both simulations, then retune get_buy_compute_unit_limit / get_sell_compute_unit_limit in platforms/pumpfun/instruction_builder.py from the reported unitsConsumed.