berry-bench-2026-06-19
1 HIGH + 1 MEDIUM in BerryJuicerFactory.createVault: unchecked transferFrom + caller-trusted amount for non-standard ERC-20s
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
- Benchmark repo: AntFleet/bench-berry
- Source repo: levyonchain/Berry-Juicer-Public @
641d9b1 - Core vault PR: bench-berry#1 — 0 unanimous findings (degraded run); review
005037fb-5054-44e0-bb0e-7e9f5e07aec0 - Factory + yield PR: bench-berry#2 — 2 unanimous findings (1 HIGH, 1 MED); review
bbf389c2-9fcf-4b45-abc3-ac9ae92196c6 - Periphery + deploy PR: bench-berry#3 — 0 unanimous findings; review
52582bd9-6e97-4b98-999c-81ec1b46216b - Token: 0x778d…1ba3 on Base