A complete, real-time liquidity sniper for BNB Chain (BSC) — it detects brand-new PancakeSwap pairs the instant they're created, runs a layered defense against rugs and honeypots, and executes a tiered exit strategy, in paper (sandbox) or real (live) mode.
LqSniper is a finished, working bot that was taken all the way to live trading with real funds on BSC. Its purpose was to answer one honest question: can a retail-speed bot profitably snipe new token launches? It does not. The bot works flawlessly; the market is the problem. See the Field Report below — the data is the real deliverable here, not a profit chart.
Educational software, provided as-is, with no warranty, and not financial advice. Sniping new launches is extremely high-risk — the overwhelming majority of new tokens are scams (rugs, honeypots, hidden mints). Live mode spends real funds and you can lose your entire stake. Only ever risk money you can afford to lose completely. We built this to learn the truth, and we're sharing the truth: at retail scale on BSC, this is a losing game.
The bot was run live (tiny size, ~$0.60/trade) across several nights. Each defense we added was beaten by an adversary that adapted to it. The progression:
| Stage of the bot | What happened live | Verdict |
|---|---|---|
| Detection + honeypot sim only | 12 / 12 losses, −83% cumulative. Every token flat then rugged in 10–18s (instant rugs the sim can't see). | rugs dominate |
| + LP lock/burn check | Overnight: 0 buys, 66 pairs skipped for unlocked LP. Re-checked later: 76% were genuinely ruggable (correct), 24% locked after launch — of those, 1 pumped, 15 faded to ~0. | the safe subset is tiny and mostly losers |
| + recursive pre-arm (wait for the lock, then buy) | Funnel finally fired buys on confirmed-locked, sim-passing tokens. | the strategy functions |
| Live result of those buys | 4 tokens passed LP lock AND the honeypot sim AND bought AND rose in price (VIT +16.7%, USDM, PUSD, USDTR — fake-stablecoin names). Then every single sell reverted → −100% each. | switchable honeypots |
The tokens that clear every filter are engineered to. They are sellable at the
instant the honeypot sim runs (so they pass), the bot buys, the deployer lets
bots accumulate for a few minutes, then flips a switch (setMaxSell(0) /
blacklist / pause) and every buyer is frozen. A honeypot sim is a point-in-time
check — it cannot detect a future state change. There is no pre-buy filter for
"the deployer will disable sells in 3 minutes," because the information does not
exist when you must decide.
BSC launches sort into exactly three buckets, and the bot proved you lose to the third no matter what:
| Token type | Defense | Outcome |
|---|---|---|
| no LP lock | LP check | ✅ skipped |
| static honeypot | honeypot sim | ✅ skipped |
| switchable honeypot | none possible | ❌ −100% |
The tokens that survive your funnel are the ones built to survive your funnel. This isn't a code weakness — it's an adaptive adversary who keeps the timing advantage. Total cost of learning this for real: ~$10. The whole "sniper bot for sale" industry is built on never admitting it.
The bot ignores established pairs (WBNB/USDC, etc.) on purpose: they're efficiently priced, and any deviation is closed in the same block by professional MEV bots on private mempools — retail edge is zero. New tokens have no price discovery yet, so the launch-to-settle gap is the only inefficiency a small bot could theoretically capture. The catch the field report exposes: that same inefficiency is exactly why the launch stream is a minefield — the scams live there because that's where the only edge is.
WebSocket (PairCreated event)
→ listener receives raw logs, pumps them into a channel
→ main drains the channel, one goroutine per pair
→ pipeline a staged funnel of gates (cheap → expensive)
decode → reserve → token → score → lp(pre-arm) → honeypot → output → trade
→ monitor tracks each position's price, runs the exit strategy, executes sells
→ executor signs & submits real swaps (live mode)
→ store SQLite record of every position and sell
Full checks cost RPC; during launch storms (50+ pairs/min) that hammers your node. So gates are ordered cheap → expensive and short-circuit early. Each pair runs in its own goroutine.
| Stage | Cost | What it does |
|---|---|---|
| decode | free | parse the event, resolve which side is the base token |
| reserve | 1 RPC | fetch reserves; skip if base liquidity is outside the window (waits for the funding Sync if empty at detection) |
| token | 2–3 RPC | symbol + decimals (cached) |
| score | in-mem + 1 RPC | suspicion scoring + repeat-deployer + rug-feedback blocklist |
| lp / pre-arm | poll, N RPC | the heart of the strategy — see below |
| honeypot | eth_simulateV1 |
simulate a real buy and sell; reject if the sell reverts or round-trip tax is too high |
| output | 1 RPC | print the surviving candidate with latency stats |
| trade | — | sandbox (paper) or live (real on-chain buy + monitor) |
The single most important — and most educational — stage. A launch reveals nothing
useful in its first second: LP isn't locked yet, and a rug pulls ~10s later. So
this stage polls the pair over a window (arm_seconds) and confirms, exiting
the moment it can:
- LP secured — the pair contract is the LP token; if ≥ 50% of its supply is
in a burn address (
0x0/0xdead) or a configured locker, it can't be rugged → buy immediately (locks at 5s → bought at ~5s, no fixed wait). - drained — reserves fell below the floor → rugged/dumped during the wait →
skip. (Needed because after a rug,
removeLiquiditycollapsestotalSupplyto the 1000-wei minimum at0x0, so a rugged pool reads ~100% "secured" — only the reserve check exposes it.) - neither within the window → never proved safe → skip.
This is what turns the bot from "race block 1 into rug spam" into "buy launches that just proved they're locked." It works — it's just that the locked tokens then turned out to be switchable honeypots (see field report).
Scoring is a noise reducer, not a loss preventer. Free/cheap signals:
round reserve +2, duplicate reserve +3, same-block deploy +3, repeat
deployer +5. 5+ → skipped as noise. Separately, when a position rugs, its
deployer is added to a persistent blocklist (SQLite-backed, loaded at startup)
so their next launch is skipped outright.
Uses eth_simulateV1 to run buy → sell in a single RPC with state carried between
calls (a fabricated wallet funded via storage override), reading real balanceOf
results. If the sell reverts (honeypot) or the round-trip loses more than
max_tax_percent, the pair is rejected. Catches static honeypots reliably;
cannot catch switchable ones (see field report). Requires a node supporting
eth_simulateV1 (e.g. QuickNode).
Config-driven; on each price update and a 5s heartbeat, sells fire in priority order. In live mode each sell is a real swap (with a slippage floor), retried a few times then written off if the pool is unsellable:
- rug guard — base reserve collapsed → dump everything
- stop loss — down past your floor vs entry → dump everything
- time exit — past the max hold → dump everything (universal backstop)
- recover — once up enough, sell exactly enough to bank capital + a buffer (dynamic size), turning the rest into a "free bag"
- trailing stop — always on: dump whatever's left on a pullback from the peak
Live mode (execution.sandbox: false) is a complete on-chain engine:
- Wallet — an encrypted V3 keystore (path in config); the passphrase comes from
the
LQSNIPER_KEY_PASSPHRASEenv var, never from disk. Import an existing key (e.g. from MetaMask) with thekeyimporthelper. - Capital ledger — polls balances on a ticker and gates every buy on funding (per base token + a native gas reserve); reserves capital for in-flight buys so concurrent pairs can't double-spend.
- Executor — builds, signs (EIP-155), and submits real V2 swaps; measures
tokens received from the
balanceOfdelta (so it reflects transfer tax). Buy and sell are symmetric; approve-once per ERC20 base. - Restart liquidation — on startup, any open live position is sold at market and closed, so a crash never strands a real bag.
- Chain-/DEX-general — router, wnative, chain id, and fees all come from config, so any Uniswap-V2-style DEX on any EVM chain works without code changes.
Requirements: Go 1.25+ and a BSC WebSocket RPC endpoint (dedicated node
recommended — free tiers rate-limit, and the honeypot check needs eth_simulateV1).
cp config.example.yml config.yml # then set chain.websocket_url to your endpoint
go build -o lqsniper ./cmd/main.go
./lqsniper # uses ./config.yml; -c for a custom pathconfig.yml is gitignored so your endpoint/key never gets committed. Sandbox is
the default — it never touches a wallet.
go build -o keyimport ./cmd/keyimport
./keyimport -o wallet.keystore # paste your private key (hidden), set a passphrase
# config.yml: execution.sandbox: false, key_file: "wallet.keystore"
export LQSNIPER_KEY_PASSPHRASE='…'
./lqsniperWallet keys (*.key, *.keystore) are gitignored. Use a throwaway wallet with
only what you'll lose.
Everything that varies lives in config.yml; code owns logic, config owns values.
See config.example.yml for the fully-commented reference.
chain— one chain per instance (websocket, wnative, base tokens, factories, LP lockers). Switch chains by editing this block.chain.base_tokens[]— capital tokens with per-token reserve windows + buy size.chain.factories[]— V2 DEX factories, each with router, swap fee, tax ceiling.chain.lp_lockers[]— locker contracts whose held LP counts as secured.arm_seconds— the pre-arm/confirmation poll window (the key strategy knob).exit— tiered exit strategy (stop loss, time exit, trailing, rug guard, recover).execution— sandbox flag, keystore path, gas reserve, gas limit, max slippage.database— SQLite path (one per instance).
cmd/main.go entry point, event loop, startup wiring
cmd/keyimport/ encrypt a private key into the keystore
src/config/ config types + YAML loader
src/listener/ WebSocket subscription + reconnect (zero business logic)
src/decoder/ PancakeSwap V2 ABI + PairCreated/Sync decoding
src/pipeline/ the staged funnel (one file per stage)
src/chain/ raw eth_call helpers (reserves, token metadata)
src/cache/ token cache, sliding-window counter, deployer blocklist
src/honeypot/ eth_simulateV1 buy/sell simulator
src/monitor/ price tracking, exit strategy, AMM fill math
src/executor/ wallet, keystore, capital ledger, real buy/sell swaps
src/store/ SQLite persistence (positions, sells, blocklist)
Finished. All phases built and validated live; the experiment is complete.
| Phase | Focus | Status |
|---|---|---|
| 1 | Real-time detection, reserve filtering, latency tracking | ✅ |
| 2 | Suspicion scoring / noise filtering / deployer blocklist | ✅ |
| 3 | Honeypot detection (sell sim, tax) | ✅ |
| 4 | AMM-accurate sandbox: paper buys/sells, monitoring, tiered exits | ✅ |
| 5 | LP lock/burn check + recursive pre-arm | ✅ |
| 6 | Live execution: wallet, ledger, real buy/sell, restart liquidation | ✅ |
| — | Verdict: retail BSC launch-sniping is unwinnable (see field report) | ✅ |
The codebase is V2-/EVM-general, so pointing it at another chain (Base, Arbitrum) is a config swap — but the field report's conclusion is a property of permissionless launches, not of BSC alone.
- Pure-Go honeypot sim — no Solidity helper; state overrides +
eth_simulateV1do buy→sell in one RPC. - Decimal-free price math — the monitor works in raw reserve ratios; decimals cancel in every comparison (gain, drop, P&L %).
- AMM-honest paper fills — sandbox sells price along the constant-product curve, so a rugged pool fills near zero and paper P&L can't hide a loss.
- Two independent WS connections — the listener owns one for the log
subscription; a separate shared client serves all
eth_callwork.
Built incrementally as a learning project, and it taught its lesson. PRs/ideas welcome — but remember the disclaimer, and the field report.
LqSniper is free software, licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later). See LICENSE for the full text.
Copyright (C) 2026 LqSniper authors
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version. This program is distributed WITHOUT ANY WARRANTY; see
the GNU General Public License for more details.