AntFleet

Agent investigation · 0xb1d0…7813

PotatoPad

1 finding2 upstream fixesupstream mergedupdated 2 months ago
token0xb1d0cd3e8307a721e3f1e1b0a2146bd9d6b67813basescan ↗tweet ↗

Upstream fixes

2 fixes landed on this agent

PRs AntFleet filed against this agent's own repo where the underlying fix landed upstream — whether via a clean merge, a separate upstream commit, or an upstream PR that ported the same fix.

SARIF backlog

CodeQL · Snyk · Semgrep

Validate scanner backlog claims through AntFleet's reachability and patch-verification gates, and emit AntFleet findings as SARIF v2.1.0 for GitHub Code Scanning.

1. Export AntFleet findings as SARIF v2.1.0
curl -L https://www.antfleet.dev/api/repos/itsfriedpotato/potatopad/findings.sarif \
  -o antfleet.sarif
2. Ingest a scanner SARIF (CodeQL / Snyk / Semgrep)

Tokens are minted server-side via pnpm exec tsx apps/web/scripts/mint-sarif-ingest-token.ts and are valid for 5 minutes. Ask the AntFleet team for one bound to your install + repo.

curl -X POST https://www.antfleet.dev/api/repos/itsfriedpotato/potatopad/sarif \
  -H "Authorization: Bearer $ANTFLEET_SARIF_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @"@codeql-results.sarif"
3. Render AntFleet findings on the GitHub Security tab

Drop the customer-owned workflow at /integrations/codescanning.yml into your repo's .github/workflows/ directory. It pulls the export above and uploads via github/codeql-action/upload-sarif.

Finding writeups

potatopad-bench-2026-07-17

RPC proxy & upload endpoints trust a spoofable X-Forwarded-For for rate limiting (trivially bypassable)

medium2 months agomerged 3b6a562

What was found

AntFleet's two-model consensus review (Claude Opus 4.7 + GPT-5.5) ran against 3 PRs on [AntFleet/bench-potatopad](https://github.com/AntFleet/bench-potatopad), a methodology fork of [itsfriedpotato/potatopad](https://github.com/itsfriedpotato/potatopad) — a direct-to-Uniswap-V3 token launchpad. The review surfaced 5 unanimous findings (4 MEDIUM, 1 LOW) across the smart-contract, web-API, and on-chain trade surfaces.

---

MEDIUM — RPC proxy & upload endpoints trust a spoofable X-Forwarded-For for rate limiting

In web/app/api/rpc/route.ts (and the Pinata-backed api/upload endpoint), the rate-limit key is derived from x-forwarded-for / x-real-ip without verifying the request actually transited a trusted proxy. Any client can set X-Forwarded-For: <random> per request and evade the limit entirely. On a single-instance deploy with no CDN in front, this makes both the Alchemy RPC proxy and the Pinata-quota-burning upload endpoint effectively unlimited.

Fix: only trust x-forwarded-for when a fixed upstream proxy is guaranteed, and additionally cap by an unspoofable key (session / wallet signature) plus a global ceiling.

---

MEDIUM — Missing swap deadline / MEV window (swaps rely solely on amountOutMinimum)

web/lib/pool.ts uses SwapRouter02's ExactInputSingleParams, which has no deadline field. A signed-but-unmined swap can sit in the mempool and be executed later when it is sandwich-profitable, bounded only by slippage. The TradeWidget offers a 10% slippage tier on low-liquidity single-sided pools — extreme sandwich exposure.

Fix: route via multicall(deadline, exactInputSingle) on SwapRouter02 (which exposes a deadline-checked multicall) or a router variant with a native deadline, and reconsider the default slippage tier.

---

MEDIUM — /api/tokens thundering herd on cold cache (no single-flight)

When the cache is empty or just expired, N concurrent requests each run a full scan() — many getLogs + getBlock calls against the same Alchemy key, amplifying load exactly when the cache is meant to prevent it.

Fix: add an in-flight promise gate so concurrent waiters await one scan.

---

MEDIUM — Dev-buy vs anti-snipe MAX_WALLET interaction reverts the whole launch

In PotatoPad._devBuy / createToken, an over-sized dev-buy during the anti-snipe window produces output above MAX_WALLET (5%), which reverts inside PotatoToken._update — rolling back the entire launch (CREATE2, pool creation, LP mint) and wasting significant gas. Flagged as policy-review: bound the dev-buy output on-chain (partial-fill + refund) or exempt the creator's own dev-buy.

---

LOW — Buy flow accepts amounts above the user's ETH balance

TradeWidget validates sell amounts against tokenBalance but not buy amounts against native ETH balance, so an oversized buy submits and fails in the wallet/RPC instead of being caught in the UI.

Fix: add a buy-side balance check (including a gas buffer) to the button disabled state and the onBuy guard.

Evidence