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.
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)
- 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 Foundation0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3(or the Timelock) per the per-contract founder actions below. Do not deploy from any other key. - 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.
- 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. - 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.
- 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.
- 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.
- 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)(passaddress(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 ReentrancyGuardhas no constructor. - Dependencies / order: none. Wave A.
- Runtime references (not constructor args):
migrateToPqcAccountandpredictPqcAccounttake afactoryargument at call time. Pass the live AerePQCAccountFactory0xd5315Ea7caa60d320c4f34b1bEd70dd9cc02CE58. - Post-deploy verification:
- Confirm NO admin: the ABI has no
owner(), nowithdraw/rescue/sweep. A call toowner()must revert (function does not exist). predictPqcAccount(0xd531…CE58, <897-byte Falcon pubKey>, <salt>)returns the same address as the live factory's ownpredictAddress(pubKey, salt)(CREATE2 parity).- A
migratewithmoveNative=falseand non-zeromsg.valuerevertsStrayNative; with an empty token array andmoveNative=falserevertsNothingToMigrate. - Run
aerenew/contracts/test/account-migrator.test.jsagainst a fork / live-like config.
- Confirm NO admin: the ABI has no
- 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). TheAereDrandQuicknetBLSlibrary is an internal library (all functionsinternal/private), so it is inlined at compile time and needs no separate deployment or--librarieslinking. - 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, noowner()).- 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
0x0AE1is 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 backgetOperator/nonceOf. submitRecoverywith a valid Falcon signature overrecordChallenge(...)appends a record and bumps the operator nonce; a tampered signature revertsPQCVerificationFailedand appends nothing.- Confirm NO owner / admin (append-only, no
owner()). - Run
aerenew/contracts/test/AereRecoveryRegistry.test.js.
- Gate: DEPLOY-WHEN-READY. CLEAN (I4:
getRecordon a bad id revertsUnknownOperator, cosmetic).
A4. intents/AereDestinationSettler
- Constructor arguments: NONE.
AERE_CHAIN_ID(2800) andFILLED_EVENT_SIGare 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
fillwhere the delivered token / recipient do not match the declared output revertsOutputMismatch; a secondfillof the same order revertsAlreadyFilled; a good fill emitsFilled, records theFillRecord, andfillCommitment(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-guestELF 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; OpenZeppelinOwnablesetsowner = 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, andvalidatorSetRoot()changes on each enroll / key rotation. - Confirm a non-validator cannot register a key for another address (
registerAttestationKeyusesmsg.sender), and a non-ownerenrollValidatorrevertsOwnable: 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:
nonRevocationVerifier_(address): PASSaddress(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 withVerifierHasNoCode(L1 fix); the zero address is explicitly allowed. Only pass the live SP1 gateway0x9ca4…0628here if you intend to wire the zk path, and even then the vkey stays 0 until the circuit is built.
ADMINis set tomsg.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/revokeare controller-only; revocation bits are terminal (clearing revertsRevocationIsTerminal), suspension bits are reversible.verifyNonRevocation(...)revertsNonRevocationNotConfiguredwhile 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:
ADMINcallssetNonRevocationVKey(<real vkey>)only once the SP1 non-revocation circuit is built. CLEAN (I2: status roots are controller-attested by design;getWordallows independent recomputation).
A7. erc8004/AereIdentityRegistry8004
- Constructor arguments:
did(address): the live AereAgentDID0xce641d7d7C10553D82b06B7C21d423550e7522C5. The constructor readskeyRegistry()from the DID and stores it asKEY_REGISTRY, so you do NOT pass the key registry separately. It revertsZeroAddresson 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 formsg.sender == KEY_REGISTRY.ownerOf(agentId)(the current Falcon-root controller) and revertsNotControllerotherwise;resolveByDomain/getAgentreturn 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:
keyRegistry_(address): live AerePQCKeyRegistry0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691.did_(address): live AereAgentDID0xce641d7d7C10553D82b06B7C21d423550e7522C5. RevertsZeroAddresson 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;respondValidationaccepts only a valid PQC signature overresponseChallenge(...)and revertsPQCValidationFailedon 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:
keyRegistry_(address): live AerePQCKeyRegistry0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691.settlementExecutor_(address): [VERIFY: supply the AERE402 settlement-executor that will callauthorizeSpendatomically with settlement. MUST be non-zero in production.] Passingaddress(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 callsauthorizeSpend, so this address is a founder integration decision (the candidate is AERE402FacilitatorV20xFC2f…91deor a purpose-built executor once wired).SETTLEMENT_EXECUTORis 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 thanSETTLEMENT_EXECUTORrevertsNotSettlementExecutor; from the executor with a valid signature within the window it records the spend and enforces the cap; a cap overflow revertsMandateCapExceeded.- 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:
keyRegistry_(address): live AerePQCKeyRegistry0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691.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:
accreditIssueris owner-only;isAccredited(id, type)is true only for an ACTIVE issuer with the type in scope;revokeIssueris terminal (a revoked issuer can never be reinstated);verifyIssuerSignatureis fail-closed. - A non-owner
accreditIssuer/suspendIssuer/revokeIssuerrevertsOwnable: 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:
facilitator(address): the live AERE402 settlement rail. PASS AERE402FacilitatorV20xFC2f7FAa94919caF1126b3c995F0F6AcCef291de(canonical; V10xbA6e…4E56is deprecated). [VERIFY: confirm the deployed facilitator'ssettle(uint256,address,address,uint256,bytes32,uint256,uint256,bytes)ABI matches theIAERE402Facilitatorinterface before relying on paid queries. The store only callssettle; theconsumedview in the interface is not called.] RevertsZeroAddresson zero.
- Dependencies / order: needs the live facilitator. Wave A.
- Post-deploy verification:
FACILITATOR()==0xFC2f…91de;COMMIT_DOMAIN()andQUERY_DOMAIN()match the constants.createStore(...)fixes owner + pricing at creation (no setters); a post-quantum store'scommitrequires a valid Falcon signature overcommitChallenge(...)(fail-closed), a classical store's requiresmsg.sender == owner.- L2 fix check:
paidQuery(..., provider, ...)records the receipt bound toprovider;attestRetrievalby any address other than that provider revertsNotReceiptProviderand 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:
zkVerifier(address): live SP1VerifierGateway0x9ca479C8c52C0EbB4599319a36a5a017BCC70628. The constructor revertsVerifierHasNoCodeif this address has no code (L1 fix), so it MUST be the live gateway.arbiter(address): [FOUNDER DECISION. Recommended: Foundation0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3.] Can only route a DISPUTED job's escrow; cannot drain. IMMUTABLE.governance(address): [FOUNDER DECISION. Recommended: Foundation0x0243…f3C3.] Can only flip the ERC-20 reward-token allowlist; cannot move funds. IMMUTABLE. RevertsZeroAddresson 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.setTokenAllowedrevertsNotGovernancefor a non-governance caller;resolveDisputerevertsNotArbiterfor a non-arbiter caller.isSolvent(address(0))andisSolvent(<token>)are true after any sequence of job lifecycle calls (the per-asset solvency invariant: balance >= totalLiabilities). A ZK_VERIFIED job pays only insidesubmitResultZKafterverifyProof; apqcSettlementjob's payout requires a valid Falcon signature oversettlementDigest(...)or revertsNotPQCAuthorized.- 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:
reputation(address): an AereAIReputation instance. For the READ path, pass the LIVE0x781ef746c08760aa854cDa4621d54db6734bfeBF. 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.]identity(address): the AereIdentityRegistry8004 deployed in A7.is Ownable; owner = deployer. RevertsZeroAddresson 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:
giveFeedbackfrom an address NOT inisAuthorizedFeedbackAuthorrevertsNotAuthorizedFeedbackAuthorand writes nothing; afteraddFeedbackAuthor(x)(owner-only),xcan submit feedback in{-1,0,+1};removeFeedbackAuthorre-blocks; only the owner manages the allowlist. canWriteThrough()is true only when the reputation instance lists this adapter as an attestor (AdapterNotAttestorotherwise).- 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:
trustRegistry_(address): the AereTrustRegistry deployed in A10.statusList_(address): the AereBitstringStatusList deployed in A6. RevertsZeroAddresson 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).anchorCredentialrevertsNotAccredited/NotYetValid/Expired/SignatureInvalidon the respective failure and records nothing;anchorCredentialWithDidenforces thedid:aere:prefix and thesubjectDidHashmatch.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:
gateway(address): live SP1VerifierGateway0x9ca479C8c52C0EbB4599319a36a5a017BCC70628. The constructor revertsVerifierHasNoCodeif code-less (L1 fix), so it MUST be the live gateway.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] indocs/AERE-PQ-AGGREGATE.mdand is NOT implemented, so a real vkey does not exist yet. Deploying now would permanently pin a placeholder. RevertsZeroVKeyon 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)enforces1 <= t <= nand a non-zero scheme;verifyAggregateis fail-closed on every binding mismatch (root / threshold / size / scheme / digest / below-threshold) and delegates the one cryptographic check toverifyProof.- 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:
gateway(address): live SP1VerifierGateway0x9ca479C8c52C0EbB4599319a36a5a017BCC70628. RevertsVerifierHasNoCodeif code-less (guard already present).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] indocs/AERE-PQ-FINALITY-CERTIFICATE.mdand is NOT implemented. RevertsZeroVKeyon zero.registry(address): the AerePQAttestationKeyRegistry deployed in A5. RevertsZeroRegistryon zero. The constructor also derivesattestationDomain = 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).verifyCertificateis 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
VerifierHasNoCodeguard.
D1. modular/AerePQAggregateModule
- Constructor arguments:
verifier(address): the AerePQAggregateVerifier deployed in C1. RevertsBadVerifieron 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))revertsUnknownCommitteeunless the committee is registered in C1;validateUserOpreturns 0 only when the signature carries a valid aggregate proof for the account's committee overuserOpHash, 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 callsauthorizeSpend. MUST NOT beaddress(0)in production (L3). Founder integration decision. - AereReputationRegistry8004 constructor arg 1,
reputation:0x781e…feBFfor 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 AERE402FacilitatorV20xFC2f…91de; confirm the deployedsettleABI matches the interface. - AereComputeMarketV3 constructor args 2 and 3,
arbiterandgovernance: founder-chosen (Foundation0x0243…f3C3recommended).
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 byADMIN(the deployer) only once the circuit exists. The contract itself deploys today withnonRevocationVerifier_ = 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.