# Vaultfire V3 Security Test Results

Date: 2026-08-20
Branch: `feat/vaultfire-v3-safe-migration`

## Foundry

Command:

```bash
cd v3-src
forge test --fuzz-runs 100000 -vv
```

Result:

- The preserved 100,000-case run completed 16 suites and 32 tests before
  the later factory and oracle-role suites were added.
- 0 tests failed.
- 0 tests skipped.
- All 15 mandatory protocol invariants have concrete fixtures and assertions.
- The ERC-4626 suite contains 14 tests.
- Seven ERC-4626 fuzz properties completed 100,000 cases each.
- Inv01 completed 64 invariant runs at depth 32 (2,048 calls) without an invariant failure.
- The integrated post-hardening suite contains 40 tests and passes at
  `--fuzz-runs 10000`.
- Five factory tests cover the deployment gate, specialized-factory bypass,
  final owner, and reward-program binding.
- Three oracle-role tests cover initialization, rotation, zero-address
  rejection, revocation of the old oracle, and authorization of the new oracle.

The complete command output is preserved in `baseline/foundry-v3-100k.txt`.

## Defects exposed and repaired

1. Bond creation attempted an illegal direct `Uninitialized -> Accepted` transition. Both bond implementations now pass through `Proposed`.
2. `Expired -> ForceExited` was unreachable because `Expired` was incorrectly terminal. Expiry is now intermediate and permissionless force exit remains available.
3. Partnership-bond surplus skimming could include pending native principal. The contract now tracks native liabilities and only permits true surplus to be skimmed.
4. `EvidenceRegistryV3` referenced an undeclared `ZeroAddress` error.
5. `RewardProgramV3` performed direct payout transfers and wrote funding state after an external token call. It now uses caller-bound pull credits, CEI, and reentrancy protection.
6. `ERC8004ValidationRegistryV3Safe` pushed slashed stake directly to the treasury. It now records treasury-specific pull credits.
7. `VaultfireBIPVaultV3` lacked the full ERC-4626/ERC-20 share surface.
8. A direct donation could reduce a positive deposit to zero shares while still pulling the depositor's assets. The vault now rejects zero-share deposits before transfer.
9. The vault did not reject fee-on-transfer assets that would create unbacked shares. Exact received-asset accounting now rejects unsupported transfers atomically.
10. Slither-reported uninitialized locals in `StreetCredV3` and `MandateRegistryV3` are now explicitly initialized.
11. `EvidenceRegistryV3` and `DisputeRegistryV3` now reject zero owners.
12. `TaskEscrowV3` duplicated the inherited `TransferFailed` custom error, preventing compilation.
13. The monolithic `SafeBondFactoryV3` exceeded EIP-170. It is now a small
    governance coordinator backed by two coordinator-only specialized
    factories; every production runtime is below 24,576 bytes.
14. Governance and oracle authority were conflated in the bond contracts.
    Both bonds now expose an independently rotatable `oracleAttestor`.

## Slither

Slither 0.11.6 was run before and after the repairs using:

```bash
cd v3-src
slither . --foundry-compile-all
```

The post-fix production-contract report contains three High and one Medium detector entries. All four were manually reviewed:

- `RewardProgramV3._transferToCaller`: false positive. The destination is fixed to `msg.sender`, the amount is limited to that caller's recorded credit, and the credit is cleared before the call.
- `ERC8004ValidationRegistryV3Safe._transferToCaller`: false positive for the same caller-bound pull-payment pattern.
- `VaultfireBIPVaultV3._deposit`: false positive. The OpenZeppelin ERC-4626 transfer path is wrapped by `nonReentrant`; the before/after balance comparison deliberately verifies exact receipt.
- `VaultfireBIPVaultV3.deposit` strict `shares == 0` equality: intentional safety check that prevents positive assets from being pulled for zero shares.

Other findings are Low, Informational, or Optimization severity. Timestamp comparisons implement explicit protocol deadlines. Optional zero-address values are documented native-asset or disable sentinels. Owner fields remain mutable where governance transfer is required and therefore should not be marked immutable.

## Scope limits

- These are local deterministic tests. No live RPC, deployment, fund transfer, key rotation, production configuration change, or mainnet transaction occurred.
- Passing local tests and static analysis does not replace an independent audit.
- The deterministic x402 facilitator/middleware sandbox is local test
  infrastructure, not proof that production facilitator regions, treasury
  configuration, or monitoring are live.
