aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md
Aere Network e4cead319d Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:01:36 +03:00

37 KiB

Aere Network: new-contracts deployment-readiness runbook

Scope: the ~17 new Solidity contracts added under aerenew/contracts/contracts/ during this build loop. Source review: aerenew/docs/AERE-SECURITY-REVIEW-NEW-CONTRACTS.md (no CRITICAL, no HIGH). Applied fixes: aerenew/docs/AERE-SECURITY-FIXES.md (M1 fixed, L1 x3 fixed, L2 fixed, L3 documented). Solc 0.8.23, OpenZeppelin v4.9.x.

STATUS: NOTHING HERE IS DEPLOYED. Every contract below is founder-gated. This document is the exact, ordered procedure to deploy and verify each one WHEN the founder greenlights it. It does not deploy anything. Confirmed on 2026-07-19 that none of these 17 contracts has a deployments/*.json entry and none appears in aerenew/sdk-js/src/addresses.ts. Activation is the founder's decision, and where noted it also requires an external audit and, for three of them, a zk circuit that does not yet exist.


0. Safety rules (read first, applies to every step)

  1. DEPLOY FROM THE DESIGNATED DEPLOYER ONLY. The frontier / inert deployer key is 0xbeB33D20dFBBD49eC7AC1F617667f1f02dfd6465. Ownable contracts start owned by this key and are then transferred to the Foundation 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3 (or the Timelock) per the per-contract founder actions below. Do not deploy from any other key.
  2. SECRET-SCAN THE REPO BEFORE ANY PUBLISH. Run the clean-repo secret scan before pushing source, verification metadata, or any artifact to a public location. No keys, no infra hostnames.
  3. NEVER TOUCH THE LIVE VALIDATORS OR THE LIVE INFRA BOX. Do not run heavy compute, provers, or deploy jobs on the infra box that serves the live RPC / explorer / relayer / oracle. Deploy transactions are submitted to https://rpc.aere.network; proving and vkey derivation run on a dedicated non-infra box that is deleted after use. Confirm RPC stays sub-second after any activity.
  4. NO NEW TOKEN. None of these contracts introduces an ERC-20 or a wrapped/governance token, and none may be modified to do so. Rewards and payments settle in native AERE or an existing allowlisted ERC-20.
  5. NEVER MOVE RESERVE OR FOUNDATION FUNDS. These deploys spend only gas from the deployer key. No transfer of Mining Reserve, Ecosystem Reserve, Team Reserve, Airdrop Reserve, or Foundation holdings is part of any step here.
  6. CODE-READY IS NOT ACTIVATION. Passing tests and a clean self-review make a contract code-ready. Going live on mainnet 2800 is a separate founder decision, and for the fund-flow contracts and the circuit-gated verifiers it is also gated on an external audit and, respectively, on a real SP1 circuit.
  7. NONE OF THESE CHANGES CONSENSUS. Every contract is application / account / settlement layer. Mainnet 2800 still seals blocks with classical secp256k1 QBFT. The Falcon / ML-DSA precompiles and the SP1 gateway are application-layer primitives. Never describe any of this as making consensus post-quantum.

1. Live addresses these contracts wire to

All values below are LIVE on mainnet 2800 and were read from aerenew/sdk-js/src/addresses.ts and aerenew/docs/AERE-EIP-COMPATIBILITY-MATRIX.md. Pass these EXACT values as constructor arguments where a contract needs them.

Ref Live address Notes
Falcon-512 precompile 0x0AE1 Live, activated block 9,189,161. Used by name in-contract (constant), not a constructor arg.
ML-DSA-44 precompile 0x0AE3 Live, activated block 9,189,161. Used by name in-contract (constant).
SP1VerifierGateway 0x9ca479C8c52C0EbB4599319a36a5a017BCC70628 Stable Succinct gateway; verifyProof reverts on an invalid proof.
AerePQCKeyRegistry 0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691 PQC public-key registry; verifyWithKey / statusOf / schemeOf.
AereAgentDID 0xce641d7d7C10553D82b06B7C21d423550e7522C5 Falcon-rooted agent identity; agentExists / getAgent / keyRegistry.
AereAIReputation 0x781ef746c08760aa854cDa4621d54db6734bfeBF Composable reputation; attestor set is Foundation-only and immutable.
AerePQCAccountFactory 0xd5315Ea7caa60d320c4f34b1bEd70dd9cc02CE58 CREATE2 factory; predictAddress(falconPubKey, salt). Runtime ref for the migrator, not a constructor arg.
AERE402FacilitatorV2 0xFC2f7FAa94919caF1126b3c995F0F6AcCef291de Canonical agentic settlement rail; settle(...). (V1 0xbA6e…4E56 is deprecated, do not wire.)
AereAgentV2 0x3FAcb997eb4252341052e7c84a86fCa0513c4490 Machine-account registry the facilitator debits.
Foundation 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3 Recommended owner / arbiter / governance target. Single-key EOA today, not a multisig.
Deployer 0xbeB33D20dFBBD49eC7AC1F617667f1f02dfd6465 The only key these are deployed from.
AereZkQbftLightClient 0xCaDA54FAb6E7AE311d240Cf0C2Df45e974156488 Origin-side finality client the destination settler's repayment path composes with (reference, not a constructor arg).
AereOutboundVerifierV2 0x08b68bd553116Dffb99E648cb764AA93930da96F Origin-side inclusion-proof pattern the settler documents (reference only).

2. Topologically-ordered deploy list

Deploy in this order. A contract may be deployed only after every contract it takes as a constructor argument already exists. Contracts inside the same wave have no dependency on each other.

WAVE A (no constructor dependency on any sibling; wire only to live addresses or nothing):

  • A1. pqc/AereAccountMigrator (no constructor args)
  • A2. oracle/AereRandomnessBeaconV2 (no constructor args; the BLS library is internal / inlined, no linking)
  • A3. AereRecoveryRegistry (no constructor args)
  • A4. intents/AereDestinationSettler (no constructor args)
  • A5. pqfinality/AerePQAttestationKeyRegistry (no constructor args; Ownable, owner = deployer)
  • A6. compliance/AereBitstringStatusList(nonRevocationVerifier) (pass address(0), see B/notes)
  • A7. erc8004/AereIdentityRegistry8004(did) (wires to live AereAgentDID)
  • A8. erc8004/AereValidationRegistry8004(keyRegistry, did) (wires to live registry + DID)
  • A9. erc8004/AereAP2MandateVerifier(keyRegistry, settlementExecutor) (wires to live registry)
  • A10. compliance/AereTrustRegistry(keyRegistry) (wires to live registry; Ownable)
  • A11. agentic/AereVectorStore(facilitator) (wires to live AERE402FacilitatorV2)
  • A12. depin/AereComputeMarketV3(zkVerifier, arbiter, governance) (wires to live SP1 gateway + Foundation)

WAVE B (depends on a Wave A output):

  • B1. erc8004/AereReputationRegistry8004(reputation, identity) (identity = A7)
  • B2. compliance/AereVerifiableCredential(trustRegistry, statusList) (trustRegistry = A10, statusList = A6)

WAVE C (CIRCUIT-GATED, do NOT deploy until the SP1 circuit and its real vkey exist):

  • C1. mpc/AerePQAggregateVerifier(gateway, aggregateProgramVKey) (gateway = live SP1; vkey is [VERIFY])
  • C2. pqfinality/AereFinalityCertificateVerifier(gateway, programVKey, registry) (registry = A5; vkey is [VERIFY])

WAVE D (depends on a Wave C output, so also circuit-gated):

  • D1. modular/AerePQAggregateModule(verifier) (verifier = C1)

Note: A6 through A12 have no dependency on A1 through A5; they are grouped in Wave A only because their sole dependencies are LIVE addresses. B1/B2 must wait for A7 / A10 / A6. C1/C2/D1 must wait for their real vkeys and, for C2 and D1, for A5 / C1.


3. Gate classification

Contract Gate Rationale
AereAccountMigrator DEPLOY-WHEN-READY (external audit recommended: moves user funds) Pure conduit, no custody, no admin. Review verdict CLEAN.
AereRandomnessBeaconV2 DEPLOY-WHEN-READY Real EIP-2537 BLS verify, fail-closed, no admin. CLEAN.
AereRecoveryRegistry DEPLOY-WHEN-READY Append-only, no admin, Falcon fail-closed. CLEAN (I4 cosmetic).
AereDestinationSettler DEPLOY-WHEN-READY; repayment loop is [MEASURE] Contract deploys with zero args; end-to-end solver repayment needs an off-chain SP1 prover + an origin-chain verifier that do not exist yet. External audit recommended (fund-flow).
AereIdentityRegistry8004 DEPLOY-WHEN-READY Controller-gated metadata over the live DID. CLEAN.
AereValidationRegistry8004 DEPLOY-WHEN-READY PQC-verified validation, no admin. CLEAN (I5 spam note).
AereAP2MandateVerifier FOUNDER-CONFIG at deploy: settlementExecutor MUST be non-zero L3: the open path (executor == 0) is replayable and is TEST-ONLY. Production must pin the AERE402 executor.
AereTrustRegistry FOUNDER-ACTION: transfer owner to Foundation, then accredit issuers Ownable trusted-list operator by design. CLEAN.
AereVerifiableCredential DEPLOY-WHEN-READY (after A10 + A6) Binds accreditation + PQC + validity + revocation, fail-closed. CLEAN.
AereBitstringStatusList DEPLOY-WHEN-READY; zk non-revocation path is CIRCUIT-GATED Deploy with verifier address(0); the SP1 non-revocation circuit is [MEASURE], so nonRevocationVKey stays 0 (path fail-closed OFF) until it exists. CLEAN (I2 by-design).
AereComputeMarketV3 EXTERNAL-AUDIT-GATED (highest-value fund flow) + FOUNDER-CONFIG (arbiter, governance) Escrow + disputes + PQC settlement. Review CLEAN, L1 fixed, but this is the one contract that custodies escrowed rewards and bonds.
AereVectorStore DEPLOY-WHEN-READY (external audit recommended: routes AERE402 funds) L2 fixed (receipt bound to provider). Settles on the live rail, custodies no balance across calls.
AerePQAttestationKeyRegistry FOUNDER-ACTION: enroll validators, each validator registers own PQ key; owner to Timelock later Append-only, no key-forgery path. CLEAN. Only meaningful in concert with C2.
AereReputationRegistry8004 FOUNDER-ACTION for WRITE-THROUGH: register adapter as attestor on a reputation instance; owner to Foundation, add feedback authors M1 fixed (owner-curated authors). READ path works against the live instance today; write-through needs a Foundation governance step.
AerePQAggregateVerifier DEPENDENCY-GATED: do NOT deploy until the SP1 aggregation circuit exists and its real vkey is known aggregateProgramVKey is IMMUTABLE. The ML-DSA-65 aggregation circuit is [MEASURE], not built. L1 fixed (code-less gateway guard).
AereFinalityCertificateVerifier DEPENDENCY-GATED: do NOT deploy until the PQ-finality aggregation circuit exists and its real vkey is known programVKey is IMMUTABLE. The circuit is [MEASURE], not built. Already carries the VerifierHasNoCode guard.
AerePQAggregateModule DEPENDENCY-GATED (through C1) Cannot be meaningfully deployed before C1, which is circuit-gated. CLEAN.

Summary:

  • DEPLOY-WHEN-READY (low risk, code-ready today): AereAccountMigrator, AereRandomnessBeaconV2, AereRecoveryRegistry, AereDestinationSettler, AereIdentityRegistry8004, AereValidationRegistry8004, AereVerifiableCredential, AereBitstringStatusList, AereVectorStore.
  • FOUNDER-CONFIG / FOUNDER-ACTION before they are useful: AereAP2MandateVerifier (executor), AereTrustRegistry (owner + accredit), AereReputationRegistry8004 (attestor grant), AerePQAttestationKeyRegistry (enroll + keys), AereComputeMarketV3 (arbiter + governance).
  • EXTERNAL-AUDIT-GATED before mainnet (fund flow): AereComputeMarketV3 (strongest), and recommended for AereVectorStore, AereDestinationSettler, AereAccountMigrator.
  • MUST NOT DEPLOY until a circuit exists: AerePQAggregateVerifier, AereFinalityCertificateVerifier, AerePQAggregateModule, and the zk non-revocation feature of AereBitstringStatusList.

4. Per-contract runbook

Each entry: constructor arguments (with the real value to pass), deploy order / dependencies, post-deploy verification, and the gate. Post-deploy eth_getCode should be non-empty for every contract; that check is implied and not repeated each time.

A1. pqc/AereAccountMigrator

  • Constructor arguments: NONE. contract AereAccountMigrator is ReentrancyGuard has no constructor.
  • Dependencies / order: none. Wave A.
  • Runtime references (not constructor args): migrateToPqcAccount and predictPqcAccount take a factory argument at call time. Pass the live AerePQCAccountFactory 0xd5315Ea7caa60d320c4f34b1bEd70dd9cc02CE58.
  • Post-deploy verification:
    • Confirm NO admin: the ABI has no owner(), no withdraw / rescue / sweep. A call to owner() must revert (function does not exist).
    • predictPqcAccount(0xd531…CE58, <897-byte Falcon pubKey>, <salt>) returns the same address as the live factory's own predictAddress(pubKey, salt) (CREATE2 parity).
    • A migrate with moveNative=false and non-zero msg.value reverts StrayNative; with an empty token array and moveNative=false reverts NothingToMigrate.
    • Run aerenew/contracts/test/account-migrator.test.js against a fork / live-like config.
  • Gate: DEPLOY-WHEN-READY. External audit recommended because it moves user balances (no custody, but it is the tx that sweeps an EOA). Verdict CLEAN.

A2. oracle/AereRandomnessBeaconV2

  • Constructor arguments: NONE. Constants only (DRAND_CHAIN_HASH, DRAND_PERIOD, DRAND_GENESIS). The AereDrandQuicknetBLS library is an internal library (all functions internal / private), so it is inlined at compile time and needs no separate deployment or --libraries linking.
  • Dependencies / order: none. Wave A. Relies on live EIP-2537 precompiles 0x05, 0x0b, 0x0f, 0x10.
  • Post-deploy verification:
    • DRAND_CHAIN_HASH() == 0x52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971, DRAND_PERIOD() == 3, DRAND_GENESIS() == 1692803367.
    • verifyRound(round, sig) with a REAL drand quicknet round returns true; with a tampered signature returns false (fail-closed). Confirm NO admin (no verification-off switch, no owner()).
    • Run aerenew/contracts/test/AereRandomnessBeaconV2.test.js.
  • Gate: DEPLOY-WHEN-READY. CLEAN. Honest note: drand BLS is classical, verifying it does not make the randomness post-quantum.

A3. AereRecoveryRegistry

  • Constructor arguments: NONE. Falcon-512 precompile 0x0AE1 is a hard-coded constant (PRECOMPILE_FALCON512).
  • Dependencies / order: none. Wave A. Requires the live Falcon-512 precompile (block 9,189,161+).
  • Post-deploy verification:
    • PRECOMPILE_FALCON512() == 0x0AE1; RECORD_DOMAIN() == keccak256("AereRecoveryRegistry.v1.record").
    • Register a watchtower Falcon key via registerOperator(pubKey), read back getOperator / nonceOf.
    • submitRecovery with a valid Falcon signature over recordChallenge(...) appends a record and bumps the operator nonce; a tampered signature reverts PQCVerificationFailed and appends nothing.
    • Confirm NO owner / admin (append-only, no owner()).
    • Run aerenew/contracts/test/AereRecoveryRegistry.test.js.
  • Gate: DEPLOY-WHEN-READY. CLEAN (I4: getRecord on a bad id reverts UnknownOperator, cosmetic).

A4. intents/AereDestinationSettler

  • Constructor arguments: NONE. AERE_CHAIN_ID (2800) and FILLED_EVENT_SIG are constants.
  • Dependencies / order: none for the deploy. Wave A.
  • Post-deploy verification:
    • AERE_CHAIN_ID() == 2800; FILLED_EVENT_SIG() == keccak256("Filled(bytes32,address,address,uint256,address,bytes32,uint64,uint64)").
    • A fill where the delivered token / recipient do not match the declared output reverts OutputMismatch; a second fill of the same order reverts AlreadyFilled; a good fill emits Filled, records the FillRecord, and fillCommitment(orderId) returns a non-zero binder.
    • Confirm NO custody / admin (solver-to-recipient direct transfer, no owner()).
    • Run aerenew/contracts/test/destination-settler.test.js.
  • Gate: DEPLOY-WHEN-READY for the on-chain filling side. The origin-chain repayment loop (SP1 prover over the qbft-lightclient-guest ELF plus an AereOutboundVerifierV2-style verifier deployed on the origin chain) is [MEASURE] and NOT part of this deploy; the settler is complete without it, but a solver is not actually repaid until that off-chain / second-chain machinery exists. External audit recommended (fund-flow, even though this contract takes no custody). CLEAN (I1: fee-on-transfer output token note).

A5. pqfinality/AerePQAttestationKeyRegistry

  • Constructor arguments: NONE. is Ownable; OpenZeppelin Ownable sets owner = msg.sender (the deployer).
  • Dependencies / order: none for the deploy. Wave A. It is a constructor dependency of C2 (AereFinalityCertificateVerifier), so it must exist before C2.
  • Post-deploy verification:
    • owner() == deployer; validatorCount() == 0; validatorSetRoot() is a deterministic value over an empty set.
    • After the founder action below: validators() returns the enrolled set in enrollment order, isSetComplete() becomes true once every enrolled validator has a key, and validatorSetRoot() changes on each enroll / key rotation.
    • Confirm a non-validator cannot register a key for another address (registerAttestationKey uses msg.sender), and a non-owner enrollValidator reverts Ownable: caller is not the owner.
    • Run aerenew/contracts/test/AerePQFinalityCertificate.test.js (covers registry + verifier).
  • Gate: FOUNDER-ACTION. The owner (Foundation, later the Timelock, founder-signed) enrolls the validator addresses; then EACH validator registers its OWN hash-based attestation key. Transfer ownership to the Foundation / Timelock after deploy. CLEAN. Note: this registry is only useful once C2 is live, which is circuit-gated.

A6. compliance/AereBitstringStatusList

  • Constructor arguments:
    1. nonRevocationVerifier_ (address): PASS address(0). This keeps the zk non-revocation path fail-closed OFF (nonRevocationConfigured() stays false) until the SP1 non-revocation circuit exists. The constructor guards a NON-ZERO but code-less address with VerifierHasNoCode (L1 fix); the zero address is explicitly allowed. Only pass the live SP1 gateway 0x9ca4…0628 here if you intend to wire the zk path, and even then the vkey stays 0 until the circuit is built.
  • ADMIN is set to msg.sender (the deployer) and is IMMUTABLE; it cannot be transferred. It can only publish the non-revocation vkey, nothing else.
  • Dependencies / order: none for the deploy. Wave A. It is a constructor dependency of B2 (AereVerifiableCredential), so it must exist before B2.
  • Post-deploy verification:
    • ADMIN() == deployer; NON_REVOCATION_VERIFIER() == address(0) (if you passed zero); nonRevocationConfigured() == false; nonRevocationVKey() == bytes32(0).
    • createList(purpose, capacity) returns a listId; setStatus / revoke are controller-only; revocation bits are terminal (clearing reverts RevocationIsTerminal), suspension bits are reversible.
    • verifyNonRevocation(...) reverts NonRevocationNotConfigured while the circuit is unset (so callers can never mistake "unconfigured" for "not revoked").
    • Run aerenew/contracts/test/aere-pq-screen.test.js (covers trust registry + VC + status list).
  • Gate: DEPLOY-WHEN-READY for the bitstring mechanism. The zk non-revocation feature is CIRCUIT-GATED: ADMIN calls setNonRevocationVKey(<real vkey>) only once the SP1 non-revocation circuit is built. CLEAN (I2: status roots are controller-attested by design; getWord allows independent recomputation).

A7. erc8004/AereIdentityRegistry8004

  • Constructor arguments:
    1. did (address): the live AereAgentDID 0xce641d7d7C10553D82b06B7C21d423550e7522C5. The constructor reads keyRegistry() from the DID and stores it as KEY_REGISTRY, so you do NOT pass the key registry separately. It reverts ZeroAddress on a zero DID or a DID that returns a zero key registry.
  • Dependencies / order: needs the live AereAgentDID. Wave A. It is a constructor dependency of B1 (AereReputationRegistry8004), so it must exist before B1.
  • Post-deploy verification:
    • DID() == 0xce64…22C5; KEY_REGISTRY() == 0x1eCa…3691 (confirms the DID rooted into the expected live key registry).
    • register(agentId, domain, cardURI) succeeds only for msg.sender == KEY_REGISTRY.ownerOf(agentId) (the current Falcon-root controller) and reverts NotController otherwise; resolveByDomain / getAgent return the bound metadata; didString(agentId) == did:aere:2800:<agentId>.
    • Confirm NO owner / admin.
    • Run aerenew/contracts/test/erc8004-adapters.test.js.
  • Gate: DEPLOY-WHEN-READY. CLEAN. [VERIFY] against the finalized ERC-8004 identity interface: Aere anchors the id to the Falcon-rooted DID id rather than minting a sequential ERC-721 id (documented divergence).

A8. erc8004/AereValidationRegistry8004

  • Constructor arguments:
    1. keyRegistry_ (address): live AerePQCKeyRegistry 0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691.
    2. did_ (address): live AereAgentDID 0xce641d7d7C10553D82b06B7C21d423550e7522C5. Reverts ZeroAddress on either being zero.
  • Dependencies / order: needs live registry + DID. Wave A.
  • Post-deploy verification:
    • KEY_REGISTRY() == 0x1eCa…3691; DID() == 0xce64…22C5.
    • precompileFor(1) == 0x0AE1 (Falcon-512), precompileFor(3) == 0x0AE3 (ML-DSA-44).
    • requestValidation(validatorKeyId, serverAgentId, dataHash) requires an ACTIVE Falcon/ML-DSA validator key and an existing server agent; respondValidation accepts only a valid PQC signature over responseChallenge(...) and reverts PQCValidationFailed on a tampered proof; a request completes exactly once.
    • Confirm NO owner / admin.
    • Run aerenew/contracts/test/erc8004-adapters.test.js.
  • Gate: DEPLOY-WHEN-READY. CLEAN (I5: permissionless request creation is storage-spam only, harmless).

A9. erc8004/AereAP2MandateVerifier

  • Constructor arguments:
    1. keyRegistry_ (address): live AerePQCKeyRegistry 0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691.
    2. settlementExecutor_ (address): [VERIFY: supply the AERE402 settlement-executor that will call authorizeSpend atomically with settlement. MUST be non-zero in production.] Passing address(0) enables the OPEN accounting path, which the security review (L3) and the fixes doc flag as TEST-ONLY: a public standing Falcon signature is replayable by anyone to exhaust a mandate's cap. There is no live facilitator today that calls authorizeSpend, so this address is a founder integration decision (the candidate is AERE402FacilitatorV2 0xFC2f…91de or a purpose-built executor once wired). SETTLEMENT_EXECUTOR is IMMUTABLE, so this is a deploy-time choice, not a later setter.
  • Dependencies / order: needs live registry. Wave A. The executor address should exist first if a real contract is used.
  • Post-deploy verification:
    • KEY_REGISTRY() == 0x1eCa…3691; SETTLEMENT_EXECUTOR() == the non-zero executor you passed.
    • verifyMandate(m, sig) (view) returns true for a valid Falcon mandate signature, false otherwise (never reverts).
    • authorizeSpend(m, amount, sig) from an address other than SETTLEMENT_EXECUTOR reverts NotSettlementExecutor; from the executor with a valid signature within the window it records the spend and enforces the cap; a cap overflow reverts MandateCapExceeded.
    • Confirm NO owner / admin and NO fund custody (cap is accounting only).
    • Run aerenew/contracts/test/erc8004-adapters.test.js (includes the settlement-executor-gate test).
  • Gate: FOUNDER-CONFIG at deploy. Production MUST pass a non-zero settlementExecutor_. CLEAN except the documented L3 open-path risk, which the non-zero executor closes.

A10. compliance/AereTrustRegistry

  • Constructor arguments:
    1. keyRegistry_ (address): live AerePQCKeyRegistry 0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691. is Ownable; owner = deployer at construction. The constructor also reserves issuer index 0 as an inert placeholder.
  • Dependencies / order: needs live registry. Wave A. It is a constructor dependency of B2 (AereVerifiableCredential), so it must exist before B2.
  • Post-deploy verification:
    • KEY_REGISTRY() == 0x1eCa…3691; owner() == deployer; issuerCount() == 0; NO_KEY() == type(uint256).max.
    • After ownership transfer + accreditation: accreditIssuer is owner-only; isAccredited(id, type) is true only for an ACTIVE issuer with the type in scope; revokeIssuer is terminal (a revoked issuer can never be reinstated); verifyIssuerSignature is fail-closed.
    • A non-owner accreditIssuer / suspendIssuer / revokeIssuer reverts Ownable: caller is not the owner.
    • Run aerenew/contracts/test/aere-pq-screen.test.js.
  • Gate: FOUNDER-ACTION. After deploy, transfer ownership to the Foundation (the trusted-list operator), then accredit real issuers. CLEAN. Deploying does not assert any real institution is accredited.

A11. agentic/AereVectorStore

  • Constructor arguments:
    1. facilitator (address): the live AERE402 settlement rail. PASS AERE402FacilitatorV2 0xFC2f7FAa94919caF1126b3c995F0F6AcCef291de (canonical; V1 0xbA6e…4E56 is deprecated). [VERIFY: confirm the deployed facilitator's settle(uint256,address,address,uint256,bytes32,uint256,uint256,bytes) ABI matches the IAERE402Facilitator interface before relying on paid queries. The store only calls settle; the consumed view in the interface is not called.] Reverts ZeroAddress on zero.
  • Dependencies / order: needs the live facilitator. Wave A.
  • Post-deploy verification:
    • FACILITATOR() == 0xFC2f…91de; COMMIT_DOMAIN() and QUERY_DOMAIN() match the constants.
    • createStore(...) fixes owner + pricing at creation (no setters); a post-quantum store's commit requires a valid Falcon signature over commitChallenge(...) (fail-closed), a classical store's requires msg.sender == owner.
    • L2 fix check: paidQuery(..., provider, ...) records the receipt bound to provider; attestRetrieval by any address other than that provider reverts NotReceiptProvider and leaves the receipt unconsumed; the bound provider consumes it successfully.
    • Confirm NO owner / admin and no balance held across calls (delta-measured forward to recipient).
    • Run aerenew/contracts/test/aere-vector-store.test.js.
  • Gate: DEPLOY-WHEN-READY. External audit recommended (routes AERE402 payments). CLEAN with L2 fixed.

A12. depin/AereComputeMarketV3

  • Constructor arguments:
    1. zkVerifier (address): live SP1VerifierGateway 0x9ca479C8c52C0EbB4599319a36a5a017BCC70628. The constructor reverts VerifierHasNoCode if this address has no code (L1 fix), so it MUST be the live gateway.
    2. arbiter (address): [FOUNDER DECISION. Recommended: Foundation 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3.] Can only route a DISPUTED job's escrow; cannot drain. IMMUTABLE.
    3. governance (address): [FOUNDER DECISION. Recommended: Foundation 0x0243…f3C3.] Can only flip the ERC-20 reward-token allowlist; cannot move funds. IMMUTABLE. Reverts ZeroAddress on any of the three being zero.
  • Dependencies / order: needs the live SP1 gateway (code check) and the two chosen roles. Wave A.
  • Post-deploy verification:
    • ZK_VERIFIER() == 0x9ca4…0628; ARBITER() == chosen arbiter; GOVERNANCE() == chosen governance; FALCON512_PRECOMPILE() == 0x0AE1.
    • setTokenAllowed reverts NotGovernance for a non-governance caller; resolveDispute reverts NotArbiter for a non-arbiter caller.
    • isSolvent(address(0)) and isSolvent(<token>) are true after any sequence of job lifecycle calls (the per-asset solvency invariant: balance >= totalLiabilities). A ZK_VERIFIED job pays only inside submitResultZK after verifyProof; a pqcSettlement job's payout requires a valid Falcon signature over settlementDigest(...) or reverts NotPQCAuthorized.
    • Confirm NO owner and no sweep (only arbiter routing + governance allowlist).
    • Run aerenew/contracts/test/AereComputeMarketV3.test.js (includes the L1 construction-guard test).
  • Gate: EXTERNAL-AUDIT-GATED before mainnet (it is the highest-value fund-flow contract: escrowed rewards + provider / challenger bonds). FOUNDER-CONFIG for arbiter and governance. CLEAN, L1 fixed.

B1. erc8004/AereReputationRegistry8004

  • Constructor arguments:
    1. reputation (address): an AereAIReputation instance. For the READ path, pass the LIVE 0x781ef746c08760aa854cDa4621d54db6734bfeBF. For WRITE-THROUGH, pass the reputation instance that LISTS THIS ADAPTER as an attestor. [VERIFY: the live instance's attestor set is Foundation-only and immutable, so write-through requires a NEW AereAIReputation instance that includes this adapter; supply that instance's address if write-through is intended.]
    2. identity (address): the AereIdentityRegistry8004 deployed in A7. is Ownable; owner = deployer. Reverts ZeroAddress on either being zero.
  • Dependencies / order: needs A7 (identity adapter) and a reputation instance. Wave B.
  • Post-deploy verification:
    • REPUTATION() == the instance passed; IDENTITY() == the A7 address; owner() == deployer.
    • getScore(agentId) / getStats(agentId) read straight from the live reputation (READ works today).
    • M1 fix check: giveFeedback from an address NOT in isAuthorizedFeedbackAuthor reverts NotAuthorizedFeedbackAuthor and writes nothing; after addFeedbackAuthor(x) (owner-only), x can submit feedback in {-1,0,+1}; removeFeedbackAuthor re-blocks; only the owner manages the allowlist.
    • canWriteThrough() is true only when the reputation instance lists this adapter as an attestor (AdapterNotAttestor otherwise).
    • Run aerenew/contracts/test/erc8004-adapters.test.js.
  • Gate: FOUNDER-ACTION for write-through. READ path is deploy-when-ready against the live instance. For write-through the Foundation must deploy / point a reputation instance that lists this adapter, then the owner authorizes feedback authors. Transfer ownership to the Foundation. M1 fixed.

B2. compliance/AereVerifiableCredential

  • Constructor arguments:
    1. trustRegistry_ (address): the AereTrustRegistry deployed in A10.
    2. statusList_ (address): the AereBitstringStatusList deployed in A6. Reverts ZeroAddress on either being zero.
  • Dependencies / order: needs A10 and A6. Wave B.
  • Post-deploy verification:
    • TRUST_REGISTRY() == A10 address; STATUS_LIST() == A6 address; DID_METHOD() == "did:aere"; VC_DOMAIN() matches the constant.
    • verifyPresented(c, sig) returns true only when accreditation + Falcon signature + validity + not-revoked all hold (fail-closed, never reverts). anchorCredential reverts NotAccredited / NotYetValid / Expired / SignatureInvalid on the respective failure and records nothing; anchorCredentialWithDid enforces the did:aere: prefix and the subjectDidHash match.
    • isValid(id) flips to false the instant the issuer is suspended / revoked in A10 or the credential's status bit is set in A6.
    • Confirm NO owner / admin.
    • Run aerenew/contracts/test/aere-pq-screen.test.js.
  • Gate: DEPLOY-WHEN-READY (after A10 + A6). CLEAN.

C1. mpc/AerePQAggregateVerifier

  • Constructor arguments:
    1. gateway (address): live SP1VerifierGateway 0x9ca479C8c52C0EbB4599319a36a5a017BCC70628. The constructor reverts VerifierHasNoCode if code-less (L1 fix), so it MUST be the live gateway.
    2. aggregateProgramVKey (bytes32): [VERIFY: supply the REAL SP1 verification key of the audited ML-DSA-65 aggregation circuit at deploy time.] This value is IMMUTABLE and pins the one circuit this verifier will ever accept. The circuit is [MEASURE] in docs/AERE-PQ-AGGREGATE.md and is NOT implemented, so a real vkey does not exist yet. Deploying now would permanently pin a placeholder. Reverts ZeroVKey on zero.
  • Dependencies / order: Wave C. It is a constructor dependency of D1 (AerePQAggregateModule).
  • Post-deploy verification (only meaningful once a real circuit + vkey exist):
    • SP1_GATEWAY() == 0x9ca4…0628; AGGREGATE_PROGRAM_VKEY() == the pinned real vkey.
    • registerCommittee(root, t, n, scheme) enforces 1 <= t <= n and a non-zero scheme; verifyAggregate is fail-closed on every binding mismatch (root / threshold / size / scheme / digest / below-threshold) and delegates the one cryptographic check to verifyProof.
    • Confirm NO owner / admin and no fund custody.
    • Run aerenew/contracts/test/AerePQAggregate.test.js (uses a MOCK gateway; the real circuit is not exercised, so passing tests do NOT prove end-to-end aggregation).
  • Gate: DEPENDENCY-GATED. DO NOT DEPLOY until the SP1 aggregation circuit exists and its real vkey is derived on a dedicated non-infra box. L1 fixed.

C2. pqfinality/AereFinalityCertificateVerifier

  • Constructor arguments:
    1. gateway (address): live SP1VerifierGateway 0x9ca479C8c52C0EbB4599319a36a5a017BCC70628. Reverts VerifierHasNoCode if code-less (guard already present).
    2. programVKey (bytes32): [VERIFY: supply the REAL SP1 vkey of the audited PQ-finality aggregation circuit at deploy time.] IMMUTABLE; pins the one circuit. The circuit is [MEASURE] in docs/AERE-PQ-FINALITY-CERTIFICATE.md and is NOT implemented. Reverts ZeroVKey on zero.
    3. registry (address): the AerePQAttestationKeyRegistry deployed in A5. Reverts ZeroRegistry on zero. The constructor also derives attestationDomain = keccak256(DOMAIN_PREFIX, chainid, registry).
  • Dependencies / order: needs A5 and a real vkey. Wave C.
  • Post-deploy verification (only meaningful once a real circuit + vkey exist):
    • SP1_GATEWAY() == 0x9ca4…0628; PROGRAM_VKEY() == the pinned real vkey; REGISTRY() == A5 address; attestationDomain() == keccak256(abi.encode(DOMAIN_PREFIX, 2800, <A5 address>)).
    • currentQuorumThreshold() == ceil(2N/3) for the live registry set (N=7 gives 5). verifyCertificate is fail-closed on root / size / domain / quorum mismatch; a rotation in A5 invalidates old certificates.
    • Confirm NO owner / admin.
    • Run aerenew/contracts/test/AerePQFinalityCertificate.test.js (MOCK gateway; real circuit not exercised).
  • Gate: DEPENDENCY-GATED. DO NOT DEPLOY until the PQ-finality aggregation circuit exists and its real vkey is known, AND A5 is deployed with the validator set enrolled and keyed. Additive to consensus, never a consensus flip. CLEAN, already carries the VerifierHasNoCode guard.

D1. modular/AerePQAggregateModule

  • Constructor arguments:
    1. verifier (address): the AerePQAggregateVerifier deployed in C1. Reverts BadVerifier on zero.
  • Dependencies / order: needs C1. Wave D. Transitively circuit-gated.
  • Post-deploy verification:
    • VERIFIER() == C1 address; isModuleType(1) == true; name() == "aere.pq-aggregate-validator.1.0.0".
    • onInstall(abi.encode(committeeId)) reverts UnknownCommittee unless the committee is registered in C1; validateUserOp returns 0 only when the signature carries a valid aggregate proof for the account's committee over userOpHash, else 1 (never reverts on a malformed signature).
    • Confirm NO owner / admin (singleton, per-account state keyed by msg.sender).
    • Run aerenew/contracts/test/AerePQAggregate.test.js.
  • Gate: DEPENDENCY-GATED (through C1). [VERIFY] the ERC-7579 signature-unwrapping against the specific account stack (Safe7579 / Kernel / Nexus) you install it under. CLEAN.

5. Consolidated [VERIFY] list (must be supplied at deploy time)

Addresses:

  • AereAP2MandateVerifier constructor arg 2, settlementExecutor_: the non-zero AERE402 settlement-executor that calls authorizeSpend. MUST NOT be address(0) in production (L3). Founder integration decision.
  • AereReputationRegistry8004 constructor arg 1, reputation: 0x781e…feBF for READ; for WRITE-THROUGH, a reputation instance that lists this adapter as an attestor (the live instance's attestor set is immutable and Foundation-only, so a new instance is required).
  • AereVectorStore constructor arg 1, facilitator: recommended AERE402FacilitatorV2 0xFC2f…91de; confirm the deployed settle ABI matches the interface.
  • AereComputeMarketV3 constructor args 2 and 3, arbiter and governance: founder-chosen (Foundation 0x0243…f3C3 recommended).

vkeys (IMMUTABLE, pin a circuit that does NOT yet exist, so these contracts must NOT deploy until the circuit is built and its real vkey is derived on a dedicated non-infra box):

  • AerePQAggregateVerifier constructor arg 2, aggregateProgramVKey: real SP1 vkey of the ML-DSA-65 aggregation circuit ([MEASURE]).
  • AereFinalityCertificateVerifier constructor arg 2, programVKey: real SP1 vkey of the PQ-finality aggregation circuit ([MEASURE]).
  • AereBitstringStatusList post-deploy setNonRevocationVKey(vkey): real SP1 vkey of the zk non-revocation circuit ([MEASURE]); set by ADMIN (the deployer) only once the circuit exists. The contract itself deploys today with nonRevocationVerifier_ = address(0).

Interface confirmations ([VERIFY] against a finalized external spec, not a deploy blocker):

  • ERC-8004 identity / reputation / validation selector conformance (the adapters keep ERC-8004 semantics but anchor ids to the Falcon-rooted DID id by design).
  • x402 / AP2 mandate field set (AereAP2MandateVerifier struct).
  • W3C VC 2.0 JSON member mapping (AereVerifiableCredential anchors a digest, not the JSON-LD document).
  • ERC-7579 signature unwrapping for the target account stack (AerePQAggregateModule).

6. What is NOT in this runbook

  • No consensus change. None of these deploys touches validator keys, QBFT config, or genesis.
  • No fund movement beyond deployer gas. No Reserve / Foundation transfer is part of any step.
  • No off-chain build. The SP1 aggregation circuits (finality, committee, non-revocation) and the destination-settler origin-side repayment prover are [MEASURE] research / engineering items tracked separately; this runbook covers only the on-chain contract deploys and their verification.