# Vaultfire — Migration Plan (PR1 revised)

**Prepared:** 2026-08-20
**Repo HEAD:** `a80144d1acbbbbf24b9eca7cd91e61daad0c0ad6`
**Scope:** Voluntary V2 → V3 migration path with rollback at every stage. No user funds move automatically at any step.

Assignment rules being enforced:
- "Migration must be voluntary and explicit."
- "Preserve V2 contracts. Do not rewrite or pretend to upgrade immutable deployed V2 contracts."
- "STOP for user review before deploy simulations."
- "Do not deploy contracts, transfer funds, rotate keys, or execute mainnet transactions without separate explicit approval."

---

## 1. Migration principles

1. **V2 stays exactly as deployed.** No `transferOwnership`, no `pause`, no config change on V2 contracts as part of migration itself. Any admin call on V2 requires a separate approval and a documented reason.
2. **V3 is additive.** New contracts, new events, new API namespace (`/api/v3/*`), new SDK exports (`VaultfireSDKv3`, `MandateModuleV3`, …).
3. **Users opt in.** Every migration action is a user-signed transaction on V3 with clear labels ("Legacy V2", "V3 test deployment", "V3 audited pilot").
4. **Every migration action is reversible up to a public deadline.** A user who moves a bond to V3 during pilot can withdraw the migrated position back to their wallet within the pilot window if pilot invariants fail.
5. **Solvency check before every migration action.** `/api/v3/protocol/solvency` returns fresh data with `finality: finalized`, or the action is refused.
6. **Kill switch is per-contract.** Pausing V3 must preserve every user's withdrawal path (Invariant #11).

---

## 2. Migration phases

### Phase 0 — PR1 baseline (this PR)

- Freeze V2 inventory (`deployments.json`, 134 instances, block context recorded).
- Freeze V2 ABIs, events, API routes, SDK signatures (checked-in schemas).
- Publish preservation contract in `V2_COMPATIBILITY_MATRIX.md`.
- Confirm P0 findings and remediation targets.

**Exit gate:** all PR1 deliverables merged to `feat/vaultfire-v3-safe-migration` locally. Nothing pushed. Nothing on mainnet.

### Phase 1 — PR2 spec + failing tests

- Deliver `V3_SPEC.md`.
- Deliver 15 failing Foundry invariant tests, one per assignment invariant, plus the "spec-completeness" invariant.
- No V3 fix code is written yet.

**Exit gate:** invariants exist as failing tests. User explicit approval before PR3.

### Phase 2 — PR3–PR6 V3 implementation on testnet

- PR3: Identity + mandate registry + EIP-712 base + ERC-1271 adapter + legacy KYA adapter.
- PR4: Safe bond factory + BondMathLib + PartnershipBondV3Safe + AccountabilityBondV3Safe + RewardProgramV3 + explicit BondState enum + ForceExit.
- PR5: StreetCredV3 (versioned, explainable) + ERC8004AdapterV3Safe + Sybil-aware attestation + slashed-ETH treasury.
- PR6: MutualAidPool (rename of AgentInsurancePool in V3 namespace) + TaskEscrowV3 (timeout/refund) + ERC-4626 property tests on VaultfireBIPVault.

Each PR ships:
- Source under `v3-src/`
- Foundry tests
- Deploy simulation to a public testnet (Base Sepolia + Amoy + Arbitrum Sepolia + Avalanche Fuji)
- Storyboard diff vs V2 with side-by-side event/function names

**Exit gate for each PR:** all invariants that PR is responsible for now pass (were failing after PR2). Repo builds under `--via-ir`. Testnet deployments verified on Sourcify.

### Phase 3 — PR7 API + SDK + x402 + indexer

- `/api/v3/*` routes deployed alongside V2.
- SDK v0.8 published side-by-side with v0.7.
- `/.well-known/x402.json` merged (V2 + V3 endpoints, both priced).
- Indexer running dual read model.
- Website labels enabled for V3 pilot tier ("V3 test deployment").

**Exit gate:** dual-stack CI green. Every response carries `protocolVersion`, `contractStatus`, `blockNumber`, `finality`, `dataSourceErrors`. `/api/contracts` regenerated from `deployments.json`.

### Phase 4 — PR8 pilot on Base

- Deploy audited V3 contracts to Base mainnet with tiny caps (see §Caps).
- `MultisigGovernanceV3` deployed and set as owner of every V3 contract.
- Multisig + timelock configured, monitoring runbook + incident runbook live.
- Bug bounty package published.
- Pilot cohort: internal + 1–2 partners (Helixa, one AI-agent partner).
- Label upgrade: `V3 audited pilot`.

**Exit gate for pilot start:** all 15 invariants passing on mainnet fork. External audit sign-off on PR3–PR6 diff vs V3.3-R3. All P0/P1 either closed or explicitly accepted with mitigation.

### Phase 5 — Voluntary user migration

- Users see, in the site:
  - Their V2 positions labeled `Legacy V2`.
  - A migration modal offering V3 with disclosure of pilot risk.
  - "Keep on V2" is the default.
- Migration mechanics per contract type:
  - **Partnership bond:** create new `PartnershipBondV3Safe`; user withdraws V2 stake to wallet (V2 path only, no automatic transfer); user separately funds V3 bond. Two independent txns; either can be aborted.
  - **Accountability bond:** same shape — user manually deactivates V2 (existing V2 path) and creates fresh V3 bond.
  - **Trust profile / StreetCred:** issue new `StreetCredV3` under the same identity; V2 badge remains, marked `Legacy V2`.
  - **Task escrow:** in-flight V2 tasks complete on V2. New tasks are created on `TaskEscrowV3`.
  - **BIP vault:** shares are not migrated; user withdraws V2 shares and deposits fresh into V3 vault after ERC-4626 property tests are green.
  - **Bridge:** V3 bridge accepts only V3 messages; V2 bridge continues to accept V2 messages.
- Every migration action is instrumented so the indexer can prove: for user `U`, `assets_v2(U) + assets_v3(U) = assets_v2(U)_before_migration + amount_funded_by_user(U)`.

### Phase 6 — Sunset

Only after:
- 90-day deprecation notice.
- Zero active positions on the deprecated V2 contract (`bondFund == 0`, `remainingStake == 0` per bond across all `bondId`s).
- A working V3 equivalent has been in production for at least 60 days.

Sunset actions on V2 are **read-only** — we stop indexing new events, we do not pause V2 (which is immutable anyway), and we mark the address `deprecated` in `deployments.json`.

---

## 3. Rollback per phase

| Phase | Trigger | Rollback |
|---|---|---|
| PR1 | Bad data in `deployments.json` | Revert commit, re-derive from live RPCs |
| PR2 | Invariant test is wrong-headed | Rewrite the test; do not weaken the invariant |
| PR3–PR6 | Testnet contract fails invariant on fork | Do not merge; iterate |
| PR7 | `/api/v3/*` breaks a V2 consumer | Feature-flag off, `NEXT_PUBLIC_ENABLE_V3=false`, keep V2 route serving |
| PR8 pilot start | Solvency check fails post-deploy | Pause V3 (kill switch); withdrawals stay open; return caps to zero |
| Pilot user migration | User reports lost value | Withdraw V3 position back to user; V2 position was untouched; investigate; no automatic replay |

---

## 4. Kill switches

Each V3 contract has:
- A `pause()` that can be called only by `MultisigGovernanceV3`.
- Pause blocks new deposits and settlements, but **never blocks user withdrawals of principal** (Invariant #11).
- `EMERGENCY_UNPAUSE_TIMELOCK` = 24h; any unpause must wait through the timelock.
- Every kill-switch event is a distinct on-chain event (`ContractPausedV3`, `ContractUnpausedV3`) and shows on `/api/v3/protocol/status`.

---

## 5. Caps for Base pilot (PR8)

| Contract | Cap | Notes |
|---|---|---|
| `PartnershipBondV3Safe` | ≤ 100 USDC total value locked | Per-bond max 25 USDC |
| `AccountabilityBondV3Safe` | ≤ 100 USDC total | Per-bond max 25 USDC |
| `TaskEscrowV3` | ≤ 100 USDC total in-flight | Per-task max 25 USDC |
| `MutualAidPool` | ≤ 50 USDC pooled | No individual payout > 25 USDC |
| `RewardProgramV3` | ≤ 50 USDC in rewards issued during pilot | Rewards paid from a separate pre-funded treasury, NEVER from bond principal (Invariant #6) |
| `VaultfireBIPVault` (V3) | not enabled until ERC-4626 tests pass in mainnet-fork PR6 | |

Caps are enforced in the contract at construct time and by the multisig at deploy time; both must agree.

---

## 6. Live actions requiring explicit owner approval

Nothing below is executed by this document.

| Action | Who | Approval |
|---|---|---|
| Deploy `MultisigGovernanceV3` on Base | `ghostkey.base.eth` via `theloopbreaker.com/deploy` | Explicit ✅ |
| `transferOwnership(multisig)` on each V3 contract | Deployer | Explicit ✅ per contract |
| Deploy V3 star bonds to Base mainnet with pilot caps | Deployer | Explicit ✅ per contract |
| Deploy V3 bridge signer set | Deployer | Explicit ✅ |
| Set feature flag `NEXT_PUBLIC_ENABLE_V3=true` on Vercel | Site owner | Explicit ✅ |
| Publish updated SDK to npm | Package owner | Explicit ✅ |
| Any `pause()` call | Multisig | Explicit ✅ per event |
| Any `unpause()` call | Multisig + 24h timelock | Explicit ✅ per event |

The V3.3-R3 audit-burner wallet (`0x5a03C962…`) has NO authority on any of the above — it is used solely for paying audit invoices and ERC-8004 review payments.

---

## 7. Communication plan

- Site banner explaining V2 vs V3 pilot, with the four allowed labels.
- Blog post at pilot start.
- Partner brief distributed only after PR7 is green.
- Public status page at `/status` reads from `/api/v3/protocol/status`.

---

## PR1 exit checklist for migration plan

- [x] Six-phase plan with per-phase gates
- [x] Rollback path for every phase
- [x] Kill-switch semantics defined (preserves withdrawals)
- [x] Pilot caps quantified
- [x] Actions requiring explicit owner approval enumerated
- [x] Migration UI implementation and tests (PR8)
- [ ] Migration UI production deployment at `/migrate`
- [ ] Monitoring runbook + incident runbook (PR8)
- [ ] Bug-bounty scope + payout matrix (PR8)
