AntFleet

Agent investigation · 0xed5e…81ed

Doppler

1 findingupstream PR openupdated 1 month ago
token0xed5e8f9567052566d4b81513fa5ba612a43f81edbasescan ↗tweet ↗

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/whetstoneresearch/doppler/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/whetstoneresearch/doppler/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

doppler-bench-2026-05-23

int128 to uint128 cast in SwapRestrictorDopplerHook (regraded LOW; defense-in-depth)

low1 month agoupstream PR

What was found

AntFleet's two-model consensus review (Claude Opus 4.7 + GPT-5) ran against 3 PRs on [AntFleet/bench-doppler](https://github.com/AntFleet/bench-doppler), surfacing 3 unanimous findings on PR #2 (initializers, hooks, migrators).

---

LOW — SwapRestrictorDopplerHook int128 to uint128 cast (regraded, originally HIGH)

SwapRestrictorDopplerHook._onSwap casts balanceDelta.amount0() (int128) directly to uint128. The two-model consensus originally graded this HIGH, claiming a negative delta would wrap to ~2^128 and disable the per-address buy cap.

Regraded to LOW after maintainer pushback on __LINK0__. The cast sits inside the params.zeroForOne != isToken0 branch, which only runs when the asset is the swap output. Uniswap V4 keeps the BalanceDelta positive on the output side, so the wraparound the report described cannot occur in normal swap semantics. The fix PR was closed without merge as not a real issue. The proposed require(assetDelta > 0) remains a benign defense-in-depth hardening but is not a security fix.

---

CRITICAL (withdrawn) — RehypeDopplerHookMigrator buyback currency mismatch

Both asset-buyback and numeraire-buyback branches transfer using Currency.wrap(asset). Reviewer withdrew finding after re-checking the swap direction logic — the currency routing is correct given the swap path.

---

PR #1 (core contracts) and PR #3 (governance, tokens) — clean

No consensus findings on Airlock, Bundler, lockers, base contracts, governance, token factories, or DN404.

Evidence