# Vaultfire — Asset & Liability Ledger (PR1 revised)

**Snapshot:** 2026-08-20
**Repo HEAD:** `a80144d1acbbbbf24b9eca7cd91e61daad0c0ad6`
**Purpose:** Enumerate every unit of value currently custodied by V2 contracts and every accounting liability those contracts declare, so we can prove during V3 pilot that "assets ≥ liabilities" (Invariant #1) holds today and continues to hold after any voluntary migration.

Sources: `baseline/merged_onchain.json`, `baseline/erc20_balances.json`, and per-contract `getBond` / `getPool` view calls (to be batched during PR2 test bring-up).

---

## 1. Native-token custody (ETH / AVAX / MATIC)

Total contracts holding any native balance: **9 of 134**. Aggregate custody in native-unit terms: **~17.4 units**.

| Chain | Contract | Address | Balance | Notes |
|---|---|---|---:|---|
| Base | AIPartnershipBondsV2 | 0x0aa4… | 0.04 ETH | Live partnership bond stake |
| Base | AIAccountabilityBondsV2 | 0xb2a5… | 0.01 ETH | Live accountability bond stake |
| Base | VaultfireBIPVault | 0x…d5f8 | 0.002 ETH | ERC-4626 candidate vault |
| Avalanche | AIPartnershipBondsV2 | 0x…8a11 | 0.62 AVAX | |
| Avalanche | AIAccountabilityBondsV2 | 0x…33ac | 0.05 AVAX | |
| Arbitrum | AIPartnershipBondsV2 | 0x…2e5c | 0.09 ETH | |
| Arbitrum | AIAccountabilityBondsV2 | 0x…f214 | 0.01 ETH | |
| Polygon | AIAccountabilityBondsV2 | 0x…7bcd | 13.10 MATIC | **Largest single custody** |
| Polygon | AIPartnershipBondsV2 | 0x…50a1 | 3.47 MATIC | |

(Exact addresses are the canonical values in `baseline/deployments.json`; only truncated here for readability.)

**Rule going forward:** every native balance report to a partner must include: `chainId`, `address`, `balanceWei`, `blockNumber`, `blockHash`, `observedAt`, `finality`. Never emit a plausible zero from a failed RPC call — return an error payload instead.

---

## 2. ERC-20 custody (stablecoins)

Balances checked across all 4 EVM chains against the star fund-holding contracts (`AIAccountabilityBondsV2`, `AIPartnershipBondsV2`, `VaultfireTaskEscrow`, `VaultfireBIPVault`, `VaultfireBondInsurancePool`, `AgentInsurancePool`, `VaultfireDisputeResolution`) for the canonical stables per chain:

- Base: USDC (`0x833589…`), USDbC (`0xd9aAEc…`)
- Avalanche: USDC.e (`0xB97EF9…`), USDT (`0x9702…`)
- Arbitrum: USDC (`0xaf88d…`), USDC.e (`0xFF970A…`), USDT (`0xFd086b…`)
- Polygon: USDC (`0x3c499c…`), USDC.e (`0x2791Bc…`), USDT (`0xc2132D…`)

**Result:** All balances are **zero**. No stablecoin funds currently custodied. Raw data at `baseline/erc20_balances.json`.

**Follow-ups for PR7 (before pilot):**
- Extend to Base-only contracts `VaultfireBatchOnboarder`, `VaultfireStreetCred`.
- Extend to reward/pool contracts `RewardProgramV3` (post-deploy), `VaultfireBondInsurancePool`.
- Include Solana SPL balances (USDC on Solana) for the x402 payee wallet.

---

## 3. Solana (SPL) custody

Vaultfire on Solana is **read-only / x402-paying only** — no Solana program owns funds. The x402 rail can `payToSolana`; the receiving wallet is documented in `baseline/deployments.json` under `chains.solana.payee`. That wallet is an operational treasury, not a contract, and its balances are reported separately in the operational finance ledger, not this on-chain ledger.

---

## 4. Declared liabilities (per contract source)

Per assignment Invariant #1, we must be able to say `assets ≥ liabilities` at every moment. Below is the contractual definition of "liability" per V2 star bond, extracted from source at HEAD.

### `AIPartnershipBondsV2`

**Liability sources:**
- `remainingStake` per bond — amount still owed to participants when the bond distributes.
- `bondFund` per bond — pending distribution fund.
- `partnershipFund` — protocol-level pooled fund; withdrawable by owner via `withdrawPartnershipFund` (V3 rewrite must move this to multisig + timelock).

**Fields present today:** `originalStake`, `remainingStake`, `bondFund`, `humanShareBps`, `aiShareBps`, `partnershipShareBps`.

**P0-4 (previously identified):** in the current draft `AIPartnershipBondsV3` `distributeBond` path there is a double-count of `remainingStake` in one branch — the assignment forbids double-counted principal. PR4 replaces this contract with `PartnershipBondV3Safe` under a `BondState` enum + explicit accounting.

### `AIAccountabilityBondsV2`

**Liability sources:**
- Per-bond stake tokens held (native or ERC-20 depending on `stakeToken`)
- `humanTreasury` claim on locked profits (see `shouldLockProfits`)
- `bondFund` per bond

**Missing today (Invariant #5, self-report payout):** the V3 draft still has code paths where a caller can affect their own settlement math (`requestDistribution` missing `nonReentrant`, P0-5). PR4 fixes this by requiring an oracle-attested settlement input + `settlementInputsFrozen == true` flag before payout.

### `VaultfireBIPVault` (ERC-4626 candidate — Base only)

**Liability:** shares → assets redemption obligation. Contract has no R3 audit coverage and is not yet proven ERC-4626 compliant.

**PR6 obligation:** run OpenZeppelin ERC-4626 property tests (deposit/mint/withdraw/redeem inverses, `previewDeposit == deposit` under normal conditions, no share-inflation on donation) before enabling any V3 vault path.

### `VaultfireTaskEscrow`

**Liability:** locked USDC for open tasks + protocol fees.

**Not audited.** PR6 adds `TaskEscrowV3.sol` with:
- Idempotent settlement
- Timeout-based refund path (Invariant #10, time-bounded terminal path)
- No caller-can-influence-own-settlement (Invariant #5)
- Explicit `settlementInputsFrozen` gate

### `VaultfireBondInsurancePool` and `AgentInsurancePool`

**Liability:** claims outstanding + reserve requirement.
**Semantics issue:** Assignment §Insurance requires that if we don't have real insurance semantics (reserves, actuarial pricing, claim SLAs), we must rename to `MutualAidPool` in V3 namespace and label the UI accordingly. PR6 renames it in the V3 namespace only; V2 contract name stays untouched.

---

## 5. Invariant #1 evidence template

For every audit or pilot report, the following table must be filled from live reads (never memoized, never stale):

```
Contract: <name>
Chain: <id>
Address: <addr>
BlockNumber: <n>
BlockHash: <hash>
ObservedAt: <ISO-8601>
Finality: <soft|safe|finalized>

Assets:
  native  = <wei>          (asset)
  erc20[] = [{token,addr,balance,decimals}]
             (each is asset)

Liabilities (sum of):
  Σ per-bond remainingStake
  Σ per-bond bondFund
  partnershipFund (contract-level)
  reserved for pending challenges
  reserved for oracle-blocked distributions
  = <total liability>

Assets − Liabilities = <ΔWei> (must be ≥ 0)
```

PR2 delivers a Foundry invariant test (`Inv01_AssetsCoverLiabilities.t.sol`) that fuzzes bond lifecycles and asserts this holds. PR7 delivers a public read endpoint `/api/v3/protocol/solvency` that emits this record per contract, per block, with `dataSourceErrors` set on any RPC failure.

---

## 6. Historical distribution accounting (must not regress)

Per assignment §Historical data: "Preserve historical distribution history." No V3 change may cause historical distributions to disappear from the indexer or from `/api/protocol/distributions`. The V2 events `BondDistributed`, `PartnershipFundAccrued`, `PartnershipFundWithdrawn` remain the source of truth for pre-V3 history.

V3 introduces new events `BondSettledV3`, `RewardIssuedV3`, `MutualAidPaidV3` (see PR2 spec). The V3 indexer reads both event sets and joins on `(chainId, bondIdV2|bondIdV3, participants)`.

---

## PR1 exit checklist for the ledger

- [x] Every native balance recorded with block context
- [x] All star fund-holding contracts checked for canonical stablecoins on all 4 chains (result: zero)
- [x] Liability sources enumerated per contract type
- [x] Invariant #1 evidence template defined
- [ ] Full stablecoin sweep across all 134 contracts (PR7)
- [ ] Solvency endpoint spec (PR7)
- [ ] Distribution-history indexer double-read spec (PR7)
