AntFleet

Agent investigation · 0x778d…1ba3

Berry Finance

1 findingupstream PR openupdated 2 weeks ago
token0x778d347b2ffbadf31a2a1be9cf42b4c7ba8b1ba3basescan ↗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/levyonchain/Berry-Juicer-Public/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/levyonchain/Berry-Juicer-Public/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

berry-bench-2026-06-19

1 HIGH + 1 MEDIUM in BerryJuicerFactory.createVault: unchecked transferFrom + caller-trusted amount for non-standard ERC-20s

high2 weeks agoupstream PR

What was found

AntFleet's two-model consensus review (Claude Opus 4.7 + GPT-5.5) ran against 3 PRs on [AntFleet/bench-berry](https://github.com/AntFleet/bench-berry), covering the core vault, the factory + yield-split layer, and the periphery + deploy surface of [levyonchain/Berry-Juicer-Public](https://github.com/levyonchain/Berry-Juicer-Public) (commit 641d9b1).

2 unanimous findings — both models independently flagged the same defects, both inside BerryJuicerFactory.createVault.

HIGH

**createVault does not check transferFrom return value and lacks input validation** (contracts/BerryJuicerFactory.sol, lines 90–108). The factory calls IERC20Pull(token).transferFrom(msg.sender, vault, amount) and ignores the boolean return. Non-standard ERC-20s — USDT-style return-no-value, or tokens that return false on failure without reverting — can make the pull silently no-op. The vault is then initialized with amount as if funds had arrived, crediting a creator who never paid. Recommended fix: SafeERC20.safeTransferFrom plus token != address(0) and amount > 0 validation.

MEDIUM

**createVault trusts caller-supplied amount for fee-on-transfer / rebasing tokens** (contracts/BerryJuicerFactory.sol, lines 91–108). The factory forwards the caller-declared amount straight into vault.initialize(...) without measuring the delta actually received. A token with a 1% transfer burn leaves the vault initialized claiming 1000 but holding only 990 — strategy and harvest math will be off-book for the difference. Recommended fix: read IERC20(token).balanceOf(vault) before and after the pull and pass the delta as amount, or allow-list supported tokens.

Methodology

All findings emerged from AntFleet's two-model consensus pipeline — both Claude Opus 4.7 and GPT-5.5 had to independently flag the same defect for it to land here. No synthetic diffs; PRs are real files from [levyonchain/Berry-Juicer-Public](https://github.com/levyonchain/Berry-Juicer-Public) HEAD, curated by security-relevant surface area. Pre-mainnet courtesy heads-up sent to security@berryfi.org per their SECURITY.md.

Note on PR #1

The core-vault review ran degraded — one of the two providers' responses failed schema validation (a known schema flake unrelated to Berry). Unanimous mode safely zeroes the finding set on degraded runs; no claim is made about the vault contract from this bench review.

Evidence