A Pons sniper bot should not be reduced to:
new launch → buy
The difficult part is everything around the transaction: identifying the right launch, checking Pons v2 state, accounting for snipe tax, calculating the curve quote, applying risk controls, simulating or executing the trade, monitoring the transaction, and reconciling the final position.
The reference implementation for this article is:
GitHub:
https://github.com/0xhamssog/pons-sniper-bot
The repository is a Pons v2 implementation for Robinhood Chain. Pons v2 starts on a bonding curve and later graduates into a Uniswap v4 pool, so its sniper logic should be treated separately from the current pool-based Pons launch architecture.
The Implementation Flow
The sniper can be thought of as one pipeline:
TokenLaunched
↓
Launch filters
↓
Snipe-tax check
↓
Curve quote
↓
Risk checks
↓
Dry run / live execution
↓
Transaction monitoring
↓
Reconciliation
The rest of the codebase exists to make those transitions reliable.
Pons v2 Is a Different Trading Model
Pons v2 starts a launch on a bonding curve:
CREATE
↓
BONDING CURVE
↓
CURVE TRADING
↓
CURVE COMPLETION
↓
UNISWAP V4
For a sniper, this means the entry logic operates against the curve rather than assuming a normal DEX pool already exists.
That affects quote calculation, tax handling, execution, and graduation logic.
1. Project Structure
A practical TypeScript implementation can be organized like this:
src/
├── chain.ts
├── clients.ts
├── protocol.ts
├── quote.ts
├── tx.ts
├── wallets.ts
├── env.ts
│
└── sniper/
├── cli.ts
├── config.ts
├── wallet.ts
├── quote/
│ └── PonsQuoteEngine.ts
└── execution/
The repository separates protocol integration, quote logic, transaction handling, wallet access, configuration, and sniper-specific behavior.
That makes it easier to change the strategy without rewriting the blockchain layer.
2. Detect New Pons v2 Launches
The first important event is:
TokenLaunched
The detector should turn that event into an internal opportunity:
type LaunchOpportunity = {
token: `0x${string}`;
curve: `0x${string}`;
deployer: `0x${string}`;
pairToken: `0x${string}`;
blockNumber: bigint;
txHash: `0x${string}`;
};
The detector's job is simply:
A new launch exists.
It should not immediately decide that the launch should be traded.
That keeps detection separate from strategy.
3. Filter the Opportunity
Not every launch should reach the quote engine.
The reference implementation supports configurable filters around areas such as:
Creator address
Token symbol
Quote asset
Reserve size
Creator tax
Snipe tax
Maximum positions
Maximum exposure
Entry frequency
Cooldown
The practical result is:
TokenLaunched
↓
Basic validation
↓
Launch filters
↓
PASS / REJECT
For one deployment, the filters might favor specific creators.
For another, they might focus on reserve size or exposure.
The protocol integration remains unchanged.
4. Snipe Tax Is Part of the Trading Decision
One of the key Pons v2 mechanics is the opening snipe tax.
The protocol exposes:
currentSnipeTaxBps(recipient)
The tax applies to buys during the opening period, so a sniper cannot calculate a curve quote and assume that the quoted token output is the final amount received.
The bot needs to ask:
Who receives the tokens?
↓
What is the current snipe tax?
↓
Is it within the strategy limit?
For example:
const snipeTaxBps =
await client.readContract({
address: curveAddress,
abi: curveAbi,
functionName: "currentSnipeTaxBps",
args: [recipient],
});
if (snipeTaxBps > maxAllowedSnipeTaxBps) {
return {
approved: false,
reason: "SNIPE_TAX_TOO_HIGH",
};
}
The reference implementation can wait for a configured acceptable tax condition instead of blindly entering the first possible block.
That is a strategy decision, not just a protocol read.
5. Build the Curve Quote From Current Protocol State
Pons v2 quoting needs the actual curve state, not a generic DEX quote.
The quote calculation should use the protocol's pricing reserves together with the relevant fee and tax inputs:
Input Amount
↓
Curve Reserves
↓
Trade Fee
↓
Creator Tax
↓
Snipe Tax
↓
Expected Output
↓
Slippage Protection
For Pons v2, getReserves() provides the curve's pricing state. The raw token balance of the contract should not simply be substituted for the pricing reserve.
Conceptually:
const [quoteReserve, tokenReserve] =
await client.readContract({
address: curveAddress,
abi: curveAbi,
functionName: "getReserves",
});
A useful quote object is:
type CurveQuote = {
amountIn: bigint;
expectedTokensOut: bigint;
minimumTokensOut: bigint;
priceImpactBps: bigint;
snipeTaxBps: bigint;
};
This gives the risk engine concrete values to inspect.
A quote is still not a guaranteed execution result.
Suppose:
Expected output:
1,000,000 TOKEN
Maximum slippage:
8%
The transaction should therefore carry a minimum acceptable output:
Curve quote
↓
Slippage limit
↓
minimumTokensOut
For example:
type ExecutionRequest = {
token: `0x${string}`;
buyAmount: bigint;
expectedTokensOut: bigint;
minimumTokensOut: bigint;
maxSlippageBps: bigint;
};
This keeps reserve state, taxes, quote calculation, and slippage protection in one coherent quote stage rather than scattering the logic across multiple layers.
6. Keep Trading Amounts Type-Safe
Use bigint for blockchain quantities:
type TokenAmount = bigint;
type QuoteAmount = bigint;
type BasisPoints = bigint;
For example:
```ts id="0ioy63"
type RiskRequest = {
buyAmount: TokenAmount;
expectedTokensOut: TokenAmount;
maxSlippageBps: BasisPoints;
};
Avoid converting token amounts to JavaScript `number` merely for convenience.
Token atomic units, quote currency, and basis points are different units and should remain explicit in the code.
---
## 7. Risk Comes Before Execution
A valid launch is not automatically a valid trade.
The reference implementation supports controls such as:
```plaintext
Maximum buy
Maximum exposure
Maximum positions
Gas reserve
Maximum snipe tax
Maximum slippage
Entry frequency
Cooldown
A risk decision can remain simple:
type RiskDecision =
| {
approved: true;
buyAmount: bigint;
}
| {
approved: false;
reason: string;
};
Rejected opportunities should be recorded explicitly.
That makes it possible to answer:
Why did the bot skip this launch?
without inspecting logs manually.
8. Dry Run Should Exercise the Real Path
A useful dry-run mode should perform the actual detection, quote, and risk logic rather than merely printing a message.
The repository supports:
npm run pons -- sniper run --dry-run
The flow can be:
Detect
↓
Filter
↓
Read snipe tax
↓
Quote
↓
Risk
↓
Simulate
without signing or broadcasting a live transaction.
That gives you a way to test the trading path with real protocol reads before enabling live execution.
9. Live Execution Should Be Explicit
Live mode is deliberately separate:
npm run pons -- sniper run --live
Combined with the repository's live-trading configuration, this creates a clear boundary between:
Development
↓
Dry run
and:
Explicit configuration
+
Explicit live command
↓
Transaction broadcast
For unattended trading, that separation is useful.
10. Use a Transaction State Machine
Once a trade is approved, the execution layer should track where it is in the lifecycle.
DETECTED
↓
VALIDATED
↓
QUOTED
↓
RISK_APPROVED
↓
TX_PREPARED
↓
SIGNED
↓
SUBMITTED
↓
PENDING
↓
CONFIRMED
Failure states should also exist:
REJECTED
REVERTED
UNKNOWN
This gives the system enough state to recover from interruptions instead of treating every transaction as a single function call.
11. RPC Timeout Does Not Automatically Mean Failure
A particularly dangerous assumption is:
RPC timeout
=
transaction failed
That is not necessarily true.
A timeout may happen after the transaction has already been submitted.
A safer sequence is:
RPC timeout
↓
UNKNOWN
↓
Inspect original transaction
↓
Confirmed?
/ \
YES NO
↓ ↓
Track Recover
The reference implementation preserves an UNKNOWN state and reconciles the original transaction before deciding what happened.
This helps avoid duplicate execution after ambiguous RPC failures.
12. Handle Partial Fills Near Graduation
Pons v2 can partially fill a final curve buy when the remaining curve inventory is smaller than the requested trade.
For example:
Requested:
1 ETH
Remaining capacity:
0.6 ETH
Actual:
partial fill
+
refund
So:
requested amount
≠
guaranteed executed amount
The position must ultimately be updated from actual execution results.
This is especially important as a launch approaches curve completion.
13. Graduation Is a State Change
A Pons v2 launch eventually moves from the curve into Uniswap v4.
That means the bot should understand the difference between:
CURVE
and:
UNISWAP V4
A focused sniper implementation can intentionally limit its entry scope to the curve phase.
That is preferable to silently mixing curve execution and post-graduation routing in the same strategy.
14. Persist Opportunities and Execution State
A live sniper needs to remember what it has already processed.
Useful persistent entities include:
opportunity
execution
transaction
position
Conceptually:
Opportunity
↓
Execution
↓
Transaction
↓
Position
After a restart, the bot should still know whether an opportunity is pending, confirmed, failed, or already reconciled.
This prevents a process restart from turning into an accidental duplicate trade.
15. Make Event Processing Recoverable
A launch detector should keep a persistent block cursor:
type IndexerCursor = {
lastProcessedBlock: bigint;
};
Processing then becomes:
Saved block
↓
Next block range
↓
Read events
↓
Persist
↓
Advance cursor
For RPC backfills, bounded block ranges are preferable to one huge getLogs request.
That gives the worker a clear recovery point after a crash or timeout.
16. Add Event Idempotency
Retries should not create duplicate opportunities.
A useful event identity is:
transaction hash + log index
A database constraint can enforce that:
UNIQUE (tx_hash, log_index)
Then a retry becomes safe:
Process range
↓
Worker fails
↓
Retry range
↓
Same event
↓
Ignored
This is a small implementation detail that makes the indexer much more reliable.
17. Example End-to-End Run
Imagine a new Pons v2 launch appears.
Detection
TokenLaunched
↓
Launch detected
Filtering
Creator accepted
Symbol accepted
Reserve acceptable
Snipe tax
Current tax
↓
Within configured limit
Quote
Buy amount
↓
Curve state
↓
Fees / taxes
↓
Expected output
Risk
Position limit
Exposure limit
Slippage
Gas reserve
↓
APPROVED
Execution
Dry run / live
↓
Transaction
↓
Monitor
Reconciliation
Receipt
↓
Actual token result
↓
Position
↓
Reconciled
18. Reference CLI
The repository provides a useful progression:
npm install
cp .env.example .env
npm run pons -- status
npm run pons -- sniper test
npm run pons -- sniper run --dry-run
npm run pons -- sniper status
npm run pons -- sniper config
npm run pons -- sniper reconcile
Live execution is explicit:
npm run pons -- sniper run --live
This makes the repository usable as both a development reference and a starting point for a larger trading application.
19. What the Repository Demonstrates
The value of the GitHub project is that it gives the implementation a concrete reference.
A potential client can inspect:
Protocol integration
Curve quote engine
Launch filters
Risk controls
Dry-run execution
Live execution
Transaction states
Recovery
Reconciliation
That is stronger proof than an article describing the same components conceptually.
GitHub:
https://github.com/0xhamssog/pons-sniper-bot
The repository also contains Pons v2 bundler functionality, but the sniper implementation is the focus here.
20. Extending the Reference Implementation
A client-specific build could add:
Creator scoring
Token scoring
Advanced launch filters
Multiple strategies
Automated take-profit
Stop-loss
Trailing exits
Telegram alerts
Discord alerts
Dashboard
REST API
WebSocket API
Multi-wallet support
Performance analytics
The existing execution foundation can remain reusable while the strategy layer changes.
For example:
Pons v2 Launch
↓
Creator score
↓
Token score
↓
Snipe tax
↓
Curve state
↓
Strategy
↓
Risk
↓
Execution
↓
Exit
Final Takeaway
The important part of a Pons v2 sniper bot is not simply detecting a TokenLaunched event.
The engineering challenge is handling everything that follows:
Launch
→ Filter
→ Snipe Tax
→ Curve Quote
→ Risk
→ Execution
→ Monitoring
→ Reconciliation
The implementation becomes much more robust when each stage owns a specific responsibility and persists enough state to recover after failures.
That is the difference between a launch listener and a trading system.
GitHub
Pons v2 Sniper Bot:
https://github.com/0xhamssog/pons-sniper-bot
Building a Custom Pons Sniper Bot?
I build custom Pons and Robinhood Chain trading systems, including Pons sniper bots, copy-trading systems, wallet trackers, launch monitors, trading terminals, token scanners, risk engines, and automated execution infrastructure.
Projects can start from an existing repository, prototype, technical specification, or a completely new system.
Top comments (0)