fix: strategy and vault hardening (replay of 2df1bb9)#3
Conversation
Smart-contract audit found strategy deposit()/withdraw() were callable by anyone, letting funds be drained directly from a strategy (bypassing the vault). Fixes: - AaveStrategy/IdleStrategy/MockYieldStrategy: bind an immutable vault and add an onlyVault modifier on deposit()/withdraw(); constructors now take the vault address (call sites + deploy scripts updated). - FloatVault: inherit ReentrancyGuard; park/withdraw/promote are nonReentrant. - AgentFloatHook: symmetric lpProvider accounting on add/remove (refund capped to actual balance); switch to forceApprove for USDT compatibility. - New regression test test_Revert_DirectStrategyWithdraw; 13/13 pass. Live mainnet remediation: redeployed the hardened AaveStrategy to 0xB433487F82572FF201A2455BF7a06325a7B8bFEa (strategy ID 4) and migrated pooled capital via the trustless on-chain promote() path. Docs updated to the new address and 13/13 test count. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AntFleet · 5 findingsBoth reviewers flagged the items below on the changed files. AntFleet posts only what two independent frontier models agree on. Bug · High — Watcher always uses testnet chain config regardless of CONFIG.chainId
Fix: Pick chain (and transport URL) based on CONFIG.chainId: e.g. chain: isMainnet ? xLayerMainnetChain : xLayerTestnetChain, and pass transport: http(CONFIG.rpcUrl). Add a regression test that verifies the client points at the configured RPC. Bug · High — FloatVault.withdraw ignores strategy’s actualOut and attempts to transfer requested amount regardless of received funds
Fix: Use the return value from IStrategy(activeStrategy).withdraw(amount) and transfer only actualOut to the caller. Consider reverting if actualOut < amount and the vault can’t make up the difference from its own balance. Update accounting consistently with the actualOut value. Bug · Medium — AgentFloatHook._beforeSwap uses regular approve (not forceApprove) on USDT-style tokens
Fix: Use Security · Medium — ALLOWED_ORIGIN defaults to '*' but Access-Control-Allow-Credentials is always 'true'
Fix: Reflect the request Origin only when it matches an allowlist, or refuse to emit Allow-Credentials when Allow-Origin is ''. At minimum, default ALLOWED_ORIGIN to a safe value rather than ''. Docs-gap · Low — README claims testsPassed=13/13 but API hardcodes testsPassed=8/8
Fix: Either remove these hardcoded fields or read them from a build artifact / forge JSON output. — Review |
AntFleet · finding
|
AntFleet · finding
|
AntFleet · finding
|
AntFleet · finding
|
AntFleet · finding
|
Benchmark replay
This PR replays upstream commit
2df1bb9("fix(security): gate strategy entry points with onlyVault + harden vault") as a diff against its parent.Scope: strategy access-control hardening, FloatVault reentrancy protection, AgentFloatHook LP accounting, token approval compatibility, deploy script updates, and regression tests.
Not for merge. Purpose: AntFleet two-model PR review evaluation.
See BENCHMARK.md for the policy.