# Spec #14: Account migration + network key rotation (quantum layer 11) Built the LAST account-layer quantum-resistance piece: a real, no-custody, tested contract for moving assets off a classical ECDSA EOA onto a post-quantum account, plus a design doc covering both that and network key rotation (gated). ## Deliverables 1. Contract: `aerenew/contracts/contracts/pqc/AereAccountMigrator.sol` (solc 0.8.23, OZ SafeERC20 + ReentrancyGuard). New file; deployed contracts untouched. - `migrate(destination, tokens[], amounts[], moveNative)`: atomic sweep of ERC-20 balances + optional native AERE from caller (old EOA) to a destination PQC account, one tx, authorized by caller's ECDSA key. - `migrateToPqcAccount(factory, falconPubKey, salt, expectedDestination, ...)`: DERIVES the destination from the Falcon-512 key via the live AerePQCAccountFactory.predictAddress, so the sweep is cryptographically bound to the PQC account that Falcon key controls. Optional expectedDestination guard. - `predictPqcAccount(...)` view for frontends. - Authorization documented BOTH ways: pre-approval (default) OR EIP-7702 delegation (Aere supports 7702 per the EIP matrix; single-tx approve+migrate). - No custody (caller is `from`, destination is `to`, one hop; native forwarded in full same-call). No owner/admin/upgrade/withdraw/rescue/sweep. Only recipient is the caller-specified destination. - Fail-closed + atomic: zero destination reverts; length/zero-token/zero-amount checks; strict native (StrayNative / ZeroNative / NothingToMigrate); any failed transfer reverts the WHOLE tx (SafeERC20). Emits Migrated(old, new, tokens, amounts, nativeAmount). 2. Test: `aerenew/contracts/test/account-migrator.test.js`. RAN it: `npx hardhat test test/account-migrator.test.js` -> **9 passing** (2026-07-19). Destination in strong-path tests is a REAL AerePQCAccount deployed via the REAL AerePQCAccountFactory (Falcon verify mocked; CREATE2 + asset moves fully real). Covers: one-tx ERC-20 migration (both entrypoints), native forward, zero-dest revert, atomicity (first token NOT moved on a failed second leg), only-destination (third party gets nothing), no-admin-drain (ABI has no owner/withdraw/rescue/ sweep; force-sent tokens unrecoverable), fail-closed native + malformed sets. 3. Doc: `aerenew/docs/AERE-QUANTUM-MIGRATION.md`. Dual: - Part A (real): harvest-now-decrypt-later rationale, the live PQC destinations (AerePQCAccount / AerePQCAccountFactory / AereHybridAuth / verifier / key registry), the contract, user flow, and the real 9/9 test result. References the pqc-migration-toolkit as the companion scanner/derivation/simulator. - Part B (design only, gated): Foundation operator key rotation = operational role transfer to a PQC/threshold account, founder-gated, NOT coupled to consensus. Validator signing key rotation = coupled to the gated consensus-PQC activation (seals are classical ECDSA QBFT today), founder + external-audit + N>=9 + soak gated. Explicit: none of this makes consensus post-quantum by itself. ## Honesty flags carried in the doc - `[VERIFY]`: live addresses (factory 0xd5315Ea7...CE58, sample account 0xa42a5e7F...4326f, verifier 0x4E8e9682...D8fFC, key registry 0x1eCa3c5A...3691); AereHybridAuth is repo source, no mainnet address; which threshold account is the intended operator destination. - `[MEASURE]`: full operator role-rotation cost across the live role set; consensus-PQC flip fork-freedom / halt-recover behavior at N>=9 soak. ## Scope boundary kept Account migration hardens ACCOUNT authorization only. It does NOT make consensus post-quantum. Validator-key rotation is coupled to the separate gated consensus-PQC item, not a today-action. No new token; no real user/Foundation funds moved (this is the mechanism, not an executed migration). No em-dashes in prose; brand "Aere Network"/"Aere", ticker AERE.