What happens between a launch and a fill
Every candidate walks the same seven stages. A candidate that fails any stage is written to the database with the reason it was dropped, which is what makes the skip log worth reading — it is the bot explaining itself.
// one candidate, start to finish TokenLaunched age gate() → 60s, so the snipe tax has decayed screen() → blocklist, caps, market cap roundTrip() → simulate the exit before spending audit() → holders, concentration, bundling deployer() → what this wallet shipped before score() → 25 features → probability pickArm() → one of 7 exit strategies buy() → Pons curve, or a v3/v4 pool manage() 6s → quick · tp1 · tp2 · trail · lock · stop train() 30m → the outcome feeds the next score
Every stage runs whether or not the bot is trading. In observation mode it still watches launches, screens them, scores them and records every decision — it simply never signs a transaction. The header shows which mode it is in.
Reading launches straight off the chain
There is no callout feed to depend on. Pons Agent subscribes to the source: the TokenLaunched event emitted by the Pons launch factories. Each log carries the token, the deployer, the paired asset, the pool, the fee tier, the block at which launch restrictions expire, and the creator's own initial buy.
// pons v2 — the live launchpad event TokenLaunched( address indexed token, address indexed curve, address indexed deployer, address pairToken, uint256 launchConfigId, uint256 graduationThreshold)
Two factory generations are live and both still produce launches. They emit byte-identical events, so the watcher queries both addresses in one eth_getLogs call rather than picking a favourite. Ranges are capped at 900 blocks per request because Orbit RPCs reject wider windows, and the cursor is persisted in Postgres so a restart resumes at the last processed block instead of replaying the chain.
Nothing is bought on sight
Seeing a launch and trading it are separate steps. A new token goes into a waiting list and is not screened until it has survived a full minute, because the deployer's own initial buy, the launch restrictions and the fastest rugs all happen inside that window — buying at block zero means buying the noisiest part of a token's life and paying for the privilege.
Age is measured from the block the token launched in, not from when the bot noticed it. That distinction matters after a restart: the log cursor rewinds, and treating "seen just now" as the launch time would make an hour-old token look brand new. Candidates that age past the far end of the window while the bot was busy are retired rather than chased.
The waiting list lives in the database, so a restart resumes it instead of dropping everything mid-wait.
- Poll interval
- 2.5s, single-flight — a slow response never stacks a second query on top of it
- Cursor
kv['pons:lastBlock'], advanced only after every log in the range is handled- Cold start
- Rewinds at most 5,000 blocks, so a long outage does not turn into a stale buying spree
- Metadata
getTokenInfo()on the token for logo, description and socials; ERC-20 calls for name, symbol, decimals
The exit is tested before the entry
Most bots check whether they can buy. The expensive question is whether they can sell. Before any capital moves, Pons Agent runs the full round trip through the QuoterV2 simulator: quote the buy, then immediately quote selling everything that buy would return.
const buy = quoteBuy(size); const back = quoteSell(buy.amountOut); retention = back / size; // must clear 0.82
A revert on the sell leg is the single most reliable honeypot tell available before committing funds — a transfer hook, a blacklist or a sell tax all surface here rather than after the position is open. Retention below MIN_ROUNDTRIP_RETENTION means the token keeps more of the trade than two pool fees can explain, and the candidate is dropped.
The rest of the screen runs cheapest-first, so database checks resolve before anything costs an RPC call:
| Gate | Default | Why |
|---|---|---|
| Quote asset | WETH only | Pons V2 allows USDG and tokenized-equity pairs; those need a two-hop exit the bot does not price yet |
| Blocklist | 7-day ban | Deployers with 3+ closed trades averaging worse than −0.2 R |
| Minimum age | 60 s | A launch has to survive its first minute before the bot will touch it |
| Maximum age | 30 min | Older than this and the entry has been missed; the candidate is dropped, not chased |
| Mint cooldown | 30 min | No double-buying the same token |
| Deployer cooldown | 60 min | One serial launcher cannot fill the whole book |
| Open positions | 20 | Marking is an RPC call per position per tick |
| Daily spend | 0.5 ETH | Rolling 24h cap, checked against actual recorded cost |
| Pool WETH | ≥ 0.15 | Liquidity that cannot absorb the exit is not liquidity |
| Price impact | ≤ 900 bps | Measured by comparing a 1% probe quote against the full size |
| Restrictions | expired | restrictionsEndBlock from the factory must be behind the head |
Twelve features, one probability
Everything that survives the screen gets scored by a logistic model that outputs one number: the probability this trade closes above break-even. Features are standardized with a running mean and variance, so a value in basis points and a 0/1 flag carry comparable weight.
Market shape
- Pool WETH at entry
- Price impact of the bot's own size
- Round-trip retention
- Initialized ticks crossed
- Graduation progress
Context
- Creator's own initial buy
- Socials present, and how many
- Deployer's prior launches and win rate
- Closest fuzzy match to a handle seen before
- Size and track record of that handle cluster
- Website domain reused from an earlier launch
- Hour of day, UTC
- Launches in the last 10 minutes
Matching handles across launches
Serial launchers almost never reuse a handle exactly. They reuse a root: moonboy_eth, then moonboy1, then moonboycoin. Every handle is normalized — the platform host is stripped, the URL reduced to its username, trailing digits and filler words like official, coin or portal removed — and compared to the last 14 days of launches by trigram overlap and edit distance, with a shared distinctive root scoring highest of all.
The obvious failure mode is that everything matches everything. A launchpad full of pepe, doge and degen handles would cluster into one giant fake identity, so roots on a generic list are capped at 0.35 no matter how well they match, and short strings are discounted. A shared website domain, which is far harder to produce by coincidence, scores 0.95.
| Handle A | Handle B | Score | Read |
|---|---|---|---|
| moonboy_eth | moonboy1 | 0.90 | Same author |
| CryptoDegen99 | cryptodegen_hq | 0.90 | Same author |
| pepeking | pepecoin | 0.35 | Same meme, damped |
| lunaris | zephyrion | 0.22 | Unrelated |
What the bot does with a match is learned, not assumed. A cluster is only a warning if that cluster's earlier trades lost money — which is exactly what handleClusterWin measures. Once a root accumulates three closed trades averaging worse than −0.2 R it is blocked for 14 days, and the block is enforced fuzzily, because the next launch will be vaultkeeper2.
Until LEARN_MIN_SAMPLES trades have closed, the model returns a flat 0.5 and every decision comes from the hard filters. The bot does not pretend to have learned something from four trades.
Buying
Swaps route through Uniswap V3 SwapRouter02 at the exact fee tier the Pons factory bound to the token at launch, so there is no tier guessing. The bot holds WETH rather than ETH: one wrap keeps every swap on the plain ERC-20 path and out of the router's payable branch, and native ETH is reserved for gas.
// pre-graduation: straight to the launch's curve curve.buy(quoteIn, minTokensOut, recipient) // native launches send value === quoteIn // after graduation: the Uniswap pool router.exactInputSingle({ tokenIn, tokenOut, fee, ... })
The position is opened from the measured fill — the balance difference before and after — not from the quote. If the fill lands more than 3% under quote, the shortfall is logged as a probable transfer tax, because that difference is the cost basis every exit rung is priced against.
| Parameter | Default | Note |
|---|---|---|
| Buy size | 0.005 ETH | Fixed per launch, kept small so the bankroll covers many of them |
| Max open | 20 | Concurrent positions, each marked every six seconds |
| Buy slippage | 1200 bps | Minted-this-minute pools move between quote and inclusion |
| Sell slippage | 1500 bps | Wider: an exit that reverts is worse than an exit that pays |
| Gas | auto | EIP-1559 fields from getFeeData; Orbit L2 fees are small but not zero |
| Nonce | serialized | One in-flight transaction at a time across the whole process |
Buys and exits share one wallet and therefore one nonce sequence. Every broadcast goes through a single queue, because two parallel sends with the same nonce means one of them silently never lands — and the one that goes missing is usually the stop loss.
Selling is the strategy
A position is never held open-endedly. It is marked every six seconds against a live quote for the size actually held, and each mark is checked against six exit conditions in priority order. Losses are always checked first — nothing else is allowed to delay a stop.
Entry filled.
| Trigger | Condition | Action |
|---|---|---|
| Stop | mult ≤ 0.75 | Sell everything. Checked first, always. |
| Break-even | mult ≤ 1.00 after TP1 | Sell the rest. A winner is not allowed to become a loser. |
| Profit lock | peaked ≥ +30%, now ≤ +10% | Sell the rest. A trade that worked does not give it all back. |
| Trail | mult ≤ peak × (1 − trail) | Sell the rest. The trail tightens as the peak rises. |
| Quick profit | +35% within 8 minutes | Bank 40% immediately. |
| TP1 / TP2 | +25% / +80% | Sell 25%, then a further 65%. |
| Time | 120 min below TP1 | Sell everything. |
The trail tightens as the trade runs
A position up 3x giving back 30% hands back far more than one up 30% giving back 30%. So the trail narrows with the peak: at 2x a 30% trail becomes roughly 15%, at 3x roughly 10%, floored at 8%. The further a winner runs, the less it is allowed to retrace.
Fast moves are banked fast
A token up 35% in three minutes and one up 35% over an hour are different animals, and the first retraces far more often. The quick-profit rule takes a slice of any move that happens inside the first few minutes. It only ever fires while in profit, so it can shorten a winner but can never turn one into a loss.
Seven exit strategies, chosen per trade
Which plan a trade gets is a bandit problem, not a prediction problem: the bot only ever observes the outcome of the plan it actually ran. One is drawn per trade by Thompson sampling, and the ones that return more get drawn more often.
| Strategy | TP1 | TP2 | Trail | Stop | Suited to |
|---|---|---|---|---|---|
| Runner | +25 / 25% | +80 / 65% | 30% | −25% | The default: de-risk early, hold for the move |
| Patient | +40 / 20% | +120 / 70% | 35% | −28% | Nothing comes off until it has genuinely worked |
| Balanced | +20 / 30% | +60 / 60% | 25% | −22% | Earlier first trim, still holds for the move |
| Quick | +12 / 50% | +30 / 35% | 15% | −20% | Choppy conditions |
| Scalper | +8 / 60% | +20 / 32% | 12% | −15% | Takes most of it at a small move |
| Moonshot | +60 / 15% | +200 / 60% | 45% | −32% | One large winner pays for many losers |
| Ratchet | +15 / 35% | +45 / 45% | 18% | −18% | Frequent trims, tightens hard as it works |
Marking
mult is the realizable value of the remaining position divided by the cost basis of that same remaining position — a quote for the exact quantity held, not the pool's mid price. On a thin curve those are very different numbers, and only one of them is a price you can actually get.
An automatic exit is not protection against a rug. It closes positions that decline; it cannot sell into a market that no longer exists. The screen catches most of those before entry, not all of them.
Two venues, one bot
Pons launches do not all live in the same place. A V1 launch lands in a Uniswap v3 pool at a fee tier the factory fixes at creation. A V2 launch runs on a bonding curve and, once it graduates, lands in a locked Uniswap v4 pool. The bot resolves which of these a token trades on before it does anything else, and every later step — quoting, the honeypot simulation, marking, exiting — runs against that venue.
| Venue | How the market is found | How it trades |
|---|---|---|
| Uniswap v3 | Factory reports the paired asset and fee tier; the pool address is looked up directly | SwapRouter02, WETH in and out |
| Uniswap v4 | No pool contract exists — the market is a key of (currency0, currency1, fee, tickSpacing, hooks), resolved by candidate elimination and confirmed against live pool state | UniversalRouter, native ETH in and out |
| Pre-graduation | Bonding curve, no pool yet | Not traded. The bot waits for a real pool |
Why v4 is treated with suspicion
Robinhood Chain is not on Uniswap's official v4 deployment list, and the UniversalRouter deployed here is a modified fork: its swap struct carries an extra trailing field, so calldata built by the stock Uniswap SDK reverts against it. There are also look-alike routers on the chain. Guessing wrong in that environment does not produce an error message, it produces a missing transaction.
So the bot never sends a v4 swap it has not already proven. It builds the calldata in both shapes — stock and the fork's variant — simulates each with eth_call from the bot wallet, and broadcasts only the one that comes back successful. The winning shape is cached so the cost is paid once. If neither simulates, the token is skipped and the reason is logged.
Every v4 address is configuration with no default. Leave them unset and the bot trades v3 only rather than pointing itself at an address nobody verified.
Launches priced in something other than ETH
Most of the launchpad does not price in ETH. Pons v2 allows USDG and tokenised equities as quote assets, and refusing those was throwing away the majority of launches — it was comfortably the largest single category of rejection in the log.
The bot now routes ETH → quote → token on the way in and back again on the way out. A quote asset with its own WETH pool is one hop. A tokenised equity is two, because equities on this chain are denominated in USDG rather than ETH, so reaching one means passing through USDG. Two-hop routes are proven by quoting them rather than by inspecting pool depth: if the quoter will not price the round trip, the route does not work regardless of how deep the pools look.
Accounting is unaffected. The bot records the ETH it actually spent acquiring the quote asset and the ETH it actually receives converting back, so a USDG- or equity-denominated position produces the same honest profit and loss as a native one, and holder payouts are never computed from a currency the bot does not hold.
Pons launches only
The bot will not buy a token the Pons factories did not launch. A token is only tradeable if getLaunchedToken on one of the two factory generations confirms it, which also supplies the paired asset, the fee tier and the deployer. Random pools that happen to exist against WETH are not candidates, and only ETH-quoted launches are traded — the USDG and tokenized-equity pairs V2 allows would need a two-hop exit the bot does not price.
Who actually owns the launch
Before buying, the bot rebuilds the entire holder list from the token's own Transfer log. That log is complete from the first block and needs no indexer, and a young launch has few enough transfers that a full reconstruction is cheap.
Concentration
Supply is measured against circulating supply — what the curve still holds is inventory, not a holder, and counting it hides the truth. The ceiling is 3% for the largest wallet.
A fixed 3% ceiling is unreachable on a young launch: with 14 holders an even split is 7.1% each, so a perfectly organic token would fail it. The absolute ceiling only applies once there are at least 34 holders. Below that, concentration is judged proportionally — is one wallet holding more than 2.5x an even share of however many holders exist.
Bundling
One wallet with 20% is a whale, and you can see them. Twenty wallets with 1% each, all funded in the same block, is the same person wearing a disguise — and the exit behaves nothing like twenty real holders.
The bot flags supply taken by wallets that first appear in a block shared with other new wallets. A single buyer per block is ordinary flow; three or more arriving together is a cluster, and the share of supply held by those clusters is the bundled percentage. Above 12% the launch is refused.
Deployer history
The bot sees every launch on the chain, not only the ones it trades, so a creator's record is far richer than its own trade history: how many tokens they have shipped, how many reached a real valuation, and how many died at the opening price. The same people launch over and over and their outcomes cluster, which makes this the most repeatable signal on a launchpad.
A wallet with at least three priced launches gets a projection — the median peak of its past launches expressed as a multiple of the opening price — with a confidence that scales with sample size. Three launches is an anecdote; thirty is a pattern. A wallet whose launches die at the open at least 90% of the time across five or more launches is banned for a fortnight.
Wallets worth watching
Every launch records who bought it first, and every launch eventually records what it was worth at its peak. Crossing those two gives a reputation for each wallet: how often it is early on something that goes somewhere, and how often it is early on something that dies at the opening price.
This is not copy trading. The bot never mirrors a position, never buys because a wallet bought, and never learns what to buy from one. What it learns is a prior — a launch that several historically-early-and-right wallets already hold is more likely to be the kind this launchpad rewards — and that prior goes into the model beside everything else. A tracked wallet buying something that fails the sell simulation still gets refused.
Scoring
A wallet's rate is shrunk toward a prior so that two-from-two does not outrank fourteen-from-twenty, and weighted by magnitude, because being early on a launch that reached $200,000 is worth more than being early on one that reached $40,000. Scores are recomputed from scratch every 45 minutes rather than incremented, which is cheap at this scale and self-heals if a pass is interrupted.
A wallet needs at least two resolved launches before it is scored at all, and the list only shows wallets above the confidence threshold. Early on, expect it to be empty: it fills in as launches resolve, not as they appear.
Run any token through the same screen
The analyzer applies exactly these checks to any address you paste, using the same code and the same thresholds the bot trades on. It has no side effects: it never records a verdict, touches a cooldown, or counts against a spend cap.
The trading path stops at the first failure because it only needs a yes or no. The analyzer runs every check and reports all of them, so you can see that a token failed on bundling but passed everything else. Results are cached briefly so a shared link cannot overload the node the bot is trading on.
| Verdict | Meaning |
|---|---|
| Would buy | Clears every check |
| Passes, low score | Safe to trade, but the model scores it below the bar |
| Would not buy | At least one hard check failed — the reason is shown |
What "it learns" actually means
Every 30 minutes the trainer reads the closed-trade history and does four bounded things. Nothing here rewrites the bot's rules — it moves dials inside limits set in the environment.
1. Retrain the entry model
Batch gradient descent over up to 1,500 closed trades, labelled by whether the trade closed above break-even. The classes are weighted, because most memecoin trades lose and an unweighted fit degenerates into "never buy" — at which point the bot stops collecting data and the model is frozen forever.
2. Re-tune the entry threshold
The threshold is set to accept roughly the top 40% of scored candidates, then clamped into [MIN_SCORE_CLAMP, MAX_SCORE_CLAMP]. Too high and the bot starves; too low and it buys the whole launchpad.
3. Update the exit bandit
Which exit ladder to use is a bandit problem, not a prediction problem: the bot only ever observes the outcome of the ladder it actually ran. Four ladders are defined in config and one is drawn per trade by Thompson sampling over a Beta posterior — an untried ladder samples uniformly and gets its shot.
| Arm | TP1 | TP2 | Trail | Stop | Time |
|---|---|---|---|---|---|
| a-tight | +10% / 60% | +20% / 30% | 12% | −20% | 30m |
| b-base | +10% / 50% | +20% / 30% | 15% | −25% | 45m |
| c-runner | +12% / 40% | +25% / 25% | 20% | −28% | 75m |
| d-scalp | +8% / 75% | +18% / 20% | 10% | −18% | 20m |
4. Promote the blocklist
Deployers with at least three closed trades averaging worse than −0.2 R get a seven-day ban, not a permanent one. Wallets get recycled and a bad week is not a life sentence.
Exploration. 15% of trades ignore the score entirely and buy anyway. Without that slice, the training set collapses onto the model's own prior: the bot only ever sees outcomes from candidates it already believed in, and it stops being able to discover that it was wrong.
Bot wallet and key handling
Pons Agent trades from one dedicated wallet on Robinhood Chain, funded only with the capital allocated to it. The address is published on the dashboard and every transaction it sends is a bot trade, verifiable on Blockscout.
- The private key lives in the host's secret store and is read once at process start to construct the signer. It is never committed, never logged, never sent anywhere.
- The wallet holds no personal funds and is not reused for anything else.
- Native ETH is kept above
MIN_GAS_RESERVE_ETH; when it dips, the bot unwraps just enough WETH to restore the reserve. - Router allowances are set once per token, to the router only.
Deployed contracts
| Contract | Address |
|---|---|
| Pons factory (active) | 0xA5aAb3F0c6EeadF30Ef1D3Eb997108E976351feB |
| Pons factory (legacy) | 0x0c37a24F5D23A486FA692d1500881d698B1F77a4 |
| WETH | 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73 |
| Uniswap V3 factory | 0x1f7d7550b1b028f7571e69a784071f0205fd2efa |
| SwapRouter02 | 0xcaf681a66d020601342297493863e78c959e5cb2 |
| QuoterV2 | 0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7 |
Every address the bot uses is checked on chain before it trades: bytecode has to exist, WETH has to actually report itself as WETH, and a live quote has to come back. Fake WETH and look-alike routers are the standard way funds vanish on a young chain, and a bot that skips those checks is one bad constant away from sending money to nobody.
Endpoints
A Node ESM Express server serves the dashboard, this documentation, and a read-only JSON API over the same Postgres the engine writes to. Everything the dashboard renders is available directly.
| Endpoint | Returns |
|---|---|
| GET /api/healthz | Liveness, chain id, whether broadcasting is enabled |
| GET /api/config | Live sizing, exit ladder defaults, filter thresholds, contract addresses |
| GET /api/launches | Recent Pons launches with the verdict and the reason for each |
| GET /api/positions | Open and stuck positions with stage, mark and peak |
| GET /api/trades | Closed trades with exit reason, PnL and R multiple |
| GET /api/fills/:id | Every buy and sell for one position, with transaction links |
| GET /api/wallet | ETH and WETH balances, plus tracked vs on-chain holdings |
| GET /api/stats | Win rate, realized PnL, equity curve, exits grouped by reason |
| GET /api/strategy | Current model version, feature weights, bandit arm table |
| GET /api/queue | Launches seen but still serving their minimum age |
| GET /api/venues | Which routing venues are live, and which router calldata shape this chain wants |
| GET /api/holders | Currently eligible wallets, per tier, with the tick history behind it |
| GET /api/revenue | Distributable profit and past airdrop rounds |
| GET /api/stream | Server-sent events: the live tail of everything the engine does |
Profit sharing
The bot's realized profit is the token's revenue. A share of closed-trade PnL is periodically distributed as ETH directly to $PONSAGENT holders. No staking, no locking, no claim transaction.
Qualifying
Holding the token at the moment a payout fires is not enough. Every five minutes the bot writes an eligibility tick for each wallet at or above the minimum, and a wallet only earns if it appears in every tick across the hold window — five minutes of continuous holding, not a balance that happened to be there once.
| Requirement | Setting | Default |
|---|---|---|
| Minimum balance | MIN_HOLD_TOKENS | 1,000,000 |
| Held continuously for | HOLD_WINDOW_MIN | 5 min |
| Balance checked every | HOLDER_TICK_MIN | 5 min |
| Still holding at payout | re-read on chain | required |
Payout weight is the lowest balance the wallet showed across the window, and again at distribution every candidate is re-read on chain — anyone who sold between the last tick and the transfer drops out, and their share redistributes to the wallets that stayed.
Buybacks
Payouts are not the only claim on profit. A second slice buys $PONSAGENT on its own market — the token is itself a Pons launch, so it routes through exactly the same v3/v4 path as everything else the bot trades — and in burn mode sends what it bought to the dead address.
| Setting | Default | Effect |
|---|---|---|
| Share of profit | 20% | Held apart from the holder payout slice; the two never spend the same ETH |
| Mode | burn | Bought tokens go to 0x…dEaD. treasury keeps them in the bot wallet instead |
| Minimum | 0.01 ETH | Below this the round waits rather than paying gas to buy dust |
| Interval | 60 min | Checked hourly, executed only when the budget clears the minimum |
A round that fails does not consume its budget: the record is marked failed and the slice returns to the pool for the next attempt. Every buy, and every burn that follows it, appears in the transaction feed with its hash.
Tiers
| Tier | Balance | Multiplier | Effect |
|---|---|---|---|
| Base | ≥ 1,000,000 | 1.00× | Straight pro rata on balance |
| Upper | ≥ 5,000,000 | 1.25× | Weight counted 25% higher than balance alone |
The multiplier applies to the weight, not to a flat bonus, so a 5M wallet earns 25% more per token than a 1M wallet — not 25% more in total. Tiers are set in HOLDER_TIERS as threshold:multiplier pairs, so adding a third band is a config change. Splitting a balance across wallets to game this loses the multiplier rather than gaining anything.
- Distributed
PAYOUT_SHARE_PCTof realized profit from closed positions, minus everything already paid out- Bought back
BUYBACK_SHARE_PCTof the same profit, spent on $PONSAGENT and burned. The remainder stays as trading capital- Split
budget × (weight ÷ total weight), where weight is balance × tier multiplier. Integer arithmetic throughout — no float rounding between the profit and the transfer- Excluded
- Burn address, the bot wallet, the token contract, plus anything in
EXCLUDE_ADDRESSES - Dust floor
- Payouts under
MIN_PAYOUT_ETHare skipped and roll into the next round rather than being spent on gas - Record
- Every round and every payout is stored with its transaction hash; live eligibility counts are at
/api/holders, past rounds at/api/revenue
Five minutes is a short window. It stops a wallet from buying seconds before a payout and selling seconds after, which is the behaviour that actually drains a distribution — but it is not a loyalty test. Raise HOLD_WINDOW_MIN if you want holding to mean something closer to holding.
A snapshot you cannot reproduce is a promise, not a mechanism. The holder set is rebuilt from public logs specifically so the distribution can be checked against the chain by anyone who cares to.
Read this part twice
Trading newly launched tokens is extremely high risk. A position can go to zero inside one block. Do not allocate funds you cannot afford to lose entirely. Nothing here is financial advice, and none of it is affiliated with or endorsed by Robinhood Markets or Pons.
What the bot fixes, and what it does not:
| Risk | Handling |
|---|---|
| Honeypot / sell tax | Round-trip simulation before entry; measured-fill check after |
| Position bleeding out | Hard stop, breakeven stop after TP1, trailing exit, time stop |
| Thin liquidity | Minimum pool WETH and a price-impact ceiling, both measured at the bot's own size |
| Serial rug deployers | Cooldowns plus an automatic seven-day blocklist driven by realized results |
| Liquidity pulled mid-position | Not solved. Marked stuck and surfaced — there is no exit to execute |
| Sequencer or RPC outage | Fallback endpoint and backoff, but a stop cannot fill while the chain is unreachable |
| Slippage on exit | Wide sell tolerance by design: filling badly beats not filling |
| The strategy being wrong | Not solved. The learner tunes an edge; it cannot create one |
The screen rejects most of what launches. That is the point, and it is also the honest summary of the whole design: on a launchpad producing thousands of tokens a day, the return comes from what the bot refuses to buy and how fast it leaves, far more than from what it picks.