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.
32 KiB
AERE Anti-MEV Design: Threshold-Encrypted Mempool and Batch-Atomic Fair Settlement
Subsystem specification. Status as of 2026-07-11. Chain ID 2800 (Hyperledger Besu QBFT, 0.5-second blocks, seven validators, one operator).
0. Honesty banner (read first)
This document describes two complementary, application-layer, opt-in anti-MEV subsystems that AERE has built and, in part, demonstrated on chain 2800:
- AereShutterMempool (V0 orchestration, V2/V3 threshold-BLS): a Shutter-style threshold-encrypted mempool that hides transaction contents until after an epoch's ordering is fixed.
- AereSettlement + AereSolverRegistry + AereVaultRelayer: a CoW-style batch-atomic settlement DEX where users sign gasless orders and an authorised solver settles the whole batch in one transaction.
What this is not, stated plainly so no reader is misled:
- This is not base-consensus MEV protection. AERE runs Hyperledger Besu QBFT. A QBFT chain cannot gain a protocol-level encrypted mempool or enshrined proposer-builder separation (PBS) without a client fork. Both subsystems live entirely in smart-contract and off-chain-service space. Validators still sign classical QBFT and order the underlying commit/settle transactions like any other transaction.
- The threshold-encrypted mempool subsystem (V2/V3) is a proof-of-concept. Its contracts were deployed to chain 2800 and exercised end-to-end, but they are not registered in the canonical SDK address registry (
aerenew/sdk-js/src/addresses.ts). Their addresses come only from repository deployment artifacts and are labeled as such throughout. Treat them as in-development, not production-registered. - The batch-settlement contracts (AereSettlement stack) are in the canonical registry and were deployed 2026-05-31, but the off-chain solver service, the order-book API, and the front-end intent toggle that would make them a live product are not yet deployed (roadmap items recorded in the deployment manifest). On-chain, the settlement contract enforces atomicity and each user's own limit price; it does not enforce a uniform clearing price or capture surplus. Those are solver-trust and Phase-2 items, detailed in section 6.
- Both subsystems depend on a single trusted coordinator/sequencer role and (for V2/V3) a trusted-dealer Shamir setup. The solver set is a permissioned allowlist with a single bootstrap solver today. These are real centralisation weaknesses, called out in section 8.
Every contract address quoted below is either verbatim from sdk-js/src/addresses.ts (marked CANONICAL) or verbatim from a repository deployment artifact under contracts/deployments/ (marked POC-ARTIFACT). No address is invented.
1. Threat model and design goals
Maximal Extractable Value (MEV) on a public chain is extracted in the gap between when a transaction is broadcast and when it is finally included and ordered. A party that can see pending transaction contents and influence ordering can front-run, back-run, and sandwich user trades. On AERE the primary ordering authority in that gap is the QBFT block proposer and, for the batch-settlement path, the solver that assembles a batch.
AERE attacks the problem from two directions at once:
- Hide the contents so that whoever orders transactions cannot tell what they contain until ordering is already fixed. This is the encrypted-mempool subsystem.
- Remove the intra-batch ordering surface so that a set of trades clears together, atomically, in one transaction, leaving no slot for an inserted sandwich. This is the batch-settlement subsystem.
Design goals, in priority order:
- A proposer or sequencer must not be able to reorder or front-run based on plaintext it saw before the ordering was committed.
- Any accepted decryption key must be provably the real threshold key, not a forgery, so decryption cannot be produced early or by a minority.
- Liveness must not be held hostage by a single withheld reveal.
- A user's downside must be bounded by its own signed limit, regardless of solver behaviour, and enforced atomically.
Non-goals for the current phase: trustless data-availability sampling, a distributed key generation (DKG) that removes the dealer, permissionless bonded solvers, on-chain uniform-price verification, and surplus capture. All are named in the roadmap (section 9).
2. Architecture overview
┌─────────────────────────────────────────────┐
user (gasless) │ ENCRYPTED MEMPOOL (opt-in, app-layer) │
───────────────► │ AereShutterMempool V2/V3 (PoC on 2800) │
ciphertext + │ commit → order → threshold-decrypt → reveal│
commitment └───────────────┬─────────────────────────────┘
│ (optional executor hook,
│ NOT wired to settlement today)
▼
┌─────────────────────────────────────────────┐
user (gasless) │ BATCH SETTLEMENT (opt-in, app-layer) │
EIP-712 order │ AereSettlement + Registry + VaultRelayer │
───────────────► │ solver assembles batch → settle() atomic │
└─────────────────────────────────────────────┘
The two subsystems are conceptually a pipeline: encrypt order flow so the ordering party is blind, then settle the resulting batch atomically. Honest note: they are independent contracts today. AereShutterMempool V2/V3 expose an optional executor address that receives execute(uint64,uint256,bytes) calls on reveal, but AereSettlement does not implement that interface, so nothing wires the mempool's reveal path into the settlement contract at present. Integrating the two (mempool executor to a settlement adapter) is a roadmap item. Each subsystem is described independently below.
3. Subsystem A1: AereShutterMempool V0 (orchestration, code-only)
Source: aerenew/contracts/contracts/mempool/AereShutterMempool.sol. Compiled artifact present; no deployment record exists in contracts/deployments/, so V0 is treated as a code-only reference stage that V2/V3 supersede.
V0 establishes the on-chain commit/reveal skeleton without real threshold cryptography. Its stated model:
- Keyper epochs. The Foundation opens a keyper epoch (
openEpoch) carrying a Merkle root of keyper BLS pubkeys and a hash of the aggregated public key. Opening a new epoch implicitly closes the prior one. At most one epoch is open at a time. - Ciphertext commitment. Anyone submits an encrypted envelope with
commit(orcommitForEpochto pin the expected epoch). Storage records the submitter, a SHA-256 hash of the ciphertext blob, an off-chain URI (ipfs/https), the block, and the epoch.envelopeId = keccak256(epochId, ciphertextHash, sender). - Key release. After
startBlock + REVEAL_DELAY_BLOCKS, the Foundation posts the epoch decryption-key commitment (releaseDecryptionKey). - Reveal.
markRevealedchecks that the submitted plaintext binds to the committed ciphertext and released key viakeccak256(abi.encodePacked(plaintext, releasedKey)) == ciphertextHash, then flags the envelope decrypt-eligible.
The V0 invariant is timing-based: ciphertexts are visible but undecipherable at block N, ordering is finalised by consensus at block N, and the key is released only at block N + REVEAL_DELAY_BLOCKS, so post-hoc reordering gains nothing.
The contract records several audit fixes in-source, worth citing because they show the failure modes that motivated V2:
- MED #31: the constructor now requires
revealDelayBlocks >= 1(a zero delay would defeat protection). - HIGH #6:
commitForEpochlets a caller pin the expected epoch, so a reorderedopenEpochcannot silently attach a ciphertext to the wrong keyper key and make it permanently undecryptable. - HIGH #4:
commitrefuses to overwrite an existing envelope slot (no double-reveal via re-commit). - HIGH #5:
releaseDecryptionKeyis one-shot per epoch (no key overwrite). - HIGH #3:
markRevealedis gated to the Foundation and requires the actual plaintext bytes, so nobody can forge aRevealedevent with an arbitrary plaintext hash.
Honest limitation of V0. The "decryption key" is a keccak placeholder, not a real threshold key. The Foundation is the sole releaser and revealer. V0 is orchestration plumbing, not cryptographic anti-MEV. V2 replaces the placeholder with a real threshold-BLS scheme verified on-chain.
4. Subsystem A2: AereShutterMempool V2 (threshold-BLS, PoC deployed)
Source: aerenew/contracts/contracts/mempool/AereShutterMempoolV2.sol.
POC-ARTIFACT address (from contracts/deployments/shutter-mempool-v2.json, not in the canonical SDK registry): 0x135100D523edA8D0AdC70e08af905dE5042A9310, deploy tx 0x87ad0d549c396bd5a002b6f9d984483ee3e16567261ff552fd3ce83fb00d3471, deploy block 8934371, coordinator 0xbeB33D20dFBBD49eC7AC1F617667f1f02dfd6465.
4.1 Cryptographic construction
V2 implements Boldyreva threshold BLS over the BLS12-381 curve and verifies it on-chain with the EIP-2537 pairing-check precompile at address 0x0f (0x00...0f). EIP-2537 is live on chain 2800 via the Pectra ruleset (BLS12-381 precompiles at 0x0b through 0x11). The contract comment records that the precompile was probed live on 2800: a valid pairing identity returns 1, garbage input reverts.
Notation used in the contract and in this spec:
- Committee master secret
s, Shamir(t, N)-shared off-chain by a dealer. - Group public key
PK = s * g2in G2. This is the epoch encryption public key. - Keyper public keys
P_i = s_i * g2in G2. These are the published verifiable-secret-sharing (VSS) commitments. - Epoch identity
H1 = hashToCurve(epoch tag)in G1. - Epoch decryption key
DK = s * H1in G1. This is the threshold signature over the epoch tag. - Keyper share
sig_i = s_i * H1in G1. DKis reconstructed off-chain fromtshares by Lagrange interpolation, then verified on-chain.
Two on-chain pairing equalities, both expressed as a product-equals-identity so the single 0x0f call decides them:
- Share validity:
e(sig_i, g2) == e(H1, P_i), checked ase(sig_i, g2) * e(-H1, P_i) == 1. - DK validity:
e(DK, g2) == e(H1, PK), checked ase(DK, g2) * e(-H1, PK) == 1.
A share or a reconstructed DK that fails its pairing reverts, so a keyper cannot post an inconsistent share and no forged DK is ever accepted. Point encodings follow EIP-2537: a G1 point is 128 bytes, a G2 point is 256 bytes, and the two-pair pairing input is 2 * 384 = 768 bytes. The helper _pairingCheck2 concatenates the four operands, staticcalls 0x0f, and returns true only when the 32-byte output decodes to 1.
4.2 Epoch lifecycle and phases
An epoch moves through Phase { None, Open, Ordered, Finalized }:
- Committee registration.
registerKeypers(addrs, pubkeys, t)is one-shot and coordinator-only. It stores each keyper's address and 256-byte G2 public key and setsthreshold = t,keyperCount = N. - Open.
startEpoch(epochId, pk, h1, h1neg)publishes the epoch encryption keyPK, the epoch identityH1, and its negation, and sets the epochOpen. - Submit. While
Open, anyone callssubmitEncrypted(epochId, ciphertext, commitment). The full ciphertext blob (U(256-byte G2) || C(payload XOR mask)) is emitted for off-chain availability; only the binding commitmentkeccak256(abi.encode(plaintext, opening))is stored, and duplicates revert. The sequencer sees only ciphertexts. - Order.
commitOrdering(epochId, orderingRoot)is sequencer-only and moves the epoch toOrdered. It commits a Merkle root over execution positions and must happen before any decryption share exists. - Shares.
submitDecryptionShare(epochId, keyperIndex, share)reverts while the epoch is stillOpenorNone(this is the no-early-decrypt guard) and reverts unless the share passes its on-chain pairing check. Each keyper index can submit once. - Finalize. Once at least
tvalid shares exist,finalizeEpoch(epochId, dk)accepts the off-chain Lagrange reconstruction only if it passes the DK pairing check, and moves the epoch toFinalized. - Reveal and execute.
revealAndExecute(epochId, index, plaintext, opening, proof)walks the committed ordering strictly in sequence (index == nextExecIndex), checks the commitment was actually submitted and not already executed, verifies Merkle membership of(epochId, index, commitment)against the committed ordering root, and confirms the plaintext opens the commitment. It then advances the cursor and optionally forwards the plaintext to the configuredexecutoras a best-effortexecute(uint64,uint256,bytes)call (a failing consumer does not roll back the reveal record).
4.3 Anti-MEV invariant (V2)
- Users submit ciphertexts plus a hiding, binding commitment while the epoch is
Open; the sequencer sees only ciphertexts. - The sequencer commits an ordering (a Merkle root over positions) before any decryption share can exist;
submitDecryptionSharereverts until ordering is committed. - Keypers post
tvalid shares; anyone reconstructsDKoff-chain; the reconstruction is pairing-verified on-chain atfinalizeEpoch. - Reveal walks the committed ordering strictly in order; a plaintext that does not open its committed value reverts, and an out-of-order reveal reverts.
Because ordering is fixed while contents are still encrypted, the party that fixes ordering cannot base that ordering on plaintext. Reordering after the fact is impossible: the ordering root is already committed, and reveals must follow it.
4.4 Keyper accountability
reportInconsistentShare(epochId, keyperIndex, allegedShare) lets anyone flag a keyper whose off-chain share is inconsistent with its on-chain VSS commitment P_i. The function reverts if the alleged share actually passes its pairing check, so false accusations are impossible. This emits a KeyperFlagged event only; it is a detection primitive, not slashing. Economic slashing of misbehaving keypers is not implemented.
4.5 Honest scope and assumptions (V2, from source)
- The symmetric unmasking step (hashing the GT pairing element to a byte mask for XOR) is done off-chain by the executor, because the
0x0fprecompile returns only a pairing-equality boolean and cannot output a GT element to hash. On-chain, the plaintext-to-commitment binding is a keccak commitment; DK correctness itself is fully pairing-verified on-chain, so decryption is deterministic and cannot be produced beforetkeypers act. PK,P_i,H1, andH1negare published by the committee dealer at registration and epoch start. A malformed published point only breaks liveness (an honest DK or share would fail its pairing); it cannot let a non-committee actor forgeDK, which still requires the master secretsthat onlyt-of-Nshares reconstruct.- The PoC uses a trusted-dealer Shamir setup. A production system would run a DKG so no single party ever holds
s. This is the single most important cryptographic caveat.
4.6 V2 known weakness (fixed in V3)
revealAndExecute advances the cursor only on a successful reveal. A single committed position whose plaintext or opening is never revealed (griefed, lost, or malformed) stalls every later position in that epoch forever. There is no skip and no timeout. V3 fixes exactly this.
4.7 V2 on-chain demonstration (from deployment artifact)
The V2 deployment artifact records an end-to-end run on chain 2800: a 3-of-5 committee, epoch 8934372 finalized with shareCount 3, an ordering root over 2 committed envelopes, and two reveal/execute transactions (0x552f6779...c7bb, 0x30f2d141...dc0c), with nextExecIndex reaching 2. The recorded dkHash is 0xbb4f9385bf208ea729a5f353434ed126212e377847db7211ac0cfe7e906f3892. These values are transcribed verbatim from shutter-mempool-v2.json; they evidence that the pairing-verified threshold path executed, not a production traffic claim.
5. Subsystem A3: AereShutterMempool V3 (liveness fix, PoC deployed)
Source: aerenew/contracts/contracts/mempool/AereShutterMempoolV3.sol.
POC-ARTIFACT address (from contracts/deployments/shutter-mempool-v3.json, not in the canonical SDK registry): 0x0C0b0560fcaa534fc30D29ae1D248CC1675281df, deploy tx 0x72f333214cc61836c334a4e82548175f658db39416f103f5124c9917b40c7fa1, deploy block 8952902, reveal window 60 seconds, coordinator 0xbeB33D20dFBBD49eC7AC1F617667f1f02dfd6465.
V3 is byte-for-byte the V2 threshold-BLS design (same 3-of-5 committee shape, same commitment binding, same out-of-order reject, same no-early-decrypt guarantee) plus one liveness fix for the reveal-timeout DoS described in 4.6.
5.1 The reveal-window escape hatch
finalizeEpochnow stamps a per-epochrevealDeadline = block.timestamp + REVEAL_WINDOW, whereREVEAL_WINDOWis an immutable constructor parameter (60 seconds in the PoC deployment).skipUnrevealed(epochId, index)advancesnextExecIndexpast the current head position, but only when all four conditions hold: the epoch isFinalized,index == nextExecIndex(skip strictly at the head),index < envelopeCount(there is a position to skip), andblock.timestamp > revealDeadline(the window has closed). It recordsskippedPosition[epochId][index]and emitsPositionSkipped.
Because skip only ever acts on the head and a successful reveal advances the head atomically, the head is by construction the still-unrevealed position: a position that was already revealed sits behind the cursor, so skipping it reverts OutOfOrder. Revealing is never gated by the deadline; revealAndExecute keeps working after the window closes, so a late-but-honest opener can still land its position. Skip is only an escape hatch for a position nobody reveals.
5.2 Permissionless-reveal invariant
The liveness argument rests on a protocol invariant that the ciphertext must embed its own opening: the encrypted blob decrypts under DK to (plaintext || opening) such that keccak256(abi.encode(plaintext, opening)) equals the committed commitment. This makes reveal permissionless: once DK is reconstructed, any holder of the decryption key can open any committed position and call revealAndExecute. A well-formed position is therefore always revealable by anyone, so skipUnrevealed only ever fires on a position whose opening was genuinely withheld, lost, or malformed, never to censor a revealable transaction. The tradeoff is a little worst-case latency: a stuck position is only skippable after REVEAL_WINDOW elapses.
5.3 V3 on-chain demonstration (from deployment artifact)
The V3 deployment artifact records the liveness fix exercised on chain 2800: epoch 8952903 finalized (dkHash 0xc435edc7fa0eff0f4d2a43556c7d5321294befb67988a03b546d261ddc06081b, revealDeadline 1783700920), position 0 deliberately left unrevealed to simulate a withheld opening, an early skipUnrevealed reverting SkipTooEarly, then a post-deadline skip (0x3ee66f74...43ca) followed by reveal of position 1 (0x39f75472...fa29), with finalNextExecIndex reaching 2. Transcribed verbatim from shutter-mempool-v3.json. This demonstrates that one stuck position no longer stalls the epoch, which was the V2 DoS.
5.4 V3 residual weaknesses
The same trusted-dealer, off-chain-unmasking, and single-coordinator caveats from 4.5 carry over unchanged. V3 fixes liveness, not decentralisation. Keyper slashing is still detection-only.
6. Subsystem B: AereSettlement, solver, and relayer (CoW-style, canonical)
Sources: aerenew/contracts/contracts/dex/AereSettlement.sol, AereSolverRegistry.sol, AereVaultRelayer.sol.
CANONICAL addresses (verbatim from sdk-js/src/addresses.ts):
AereSettlement=0x9C2957b1622567B4802E4AFd4c42FB2ec70dE875(Tier-1.9 batch-auction DEX, deployed 2026-05-31)AereSolverRegistry=0xDBD29332a9993d2816EF0bD240288E03a8103f3BAereVaultRelayer=0x9FCA122e87E36D7cba20DbEA7b9b7354A4Cece91
The settlement-stack deployment artifact additionally records a bootstrap solver 0xE04587e0c6da6a30a24EFe7d59701A2BfFb706d9 and Foundation owner 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3.
6.1 What it is
A simplified port of CoW Protocol's GPv2 stack. Users sign EIP-712 Order structs off-chain (gasless). An authorised solver collects open orders and submits the whole batch atomically via settle(orders, signatures, executions). MEV protection comes from atomicity: because the whole batch executes in one transaction, no actor can insert a sandwich between two orders in the batch.
The Order struct carries user, sellToken, buyToken, sellAmount (exact, fill-or-kill in v1), minBuyAmount (the user's own slippage floor), validTo (unix deadline), and salt (per-user replay nonce). The Execution struct carries just executedBuyAmount, the solver's claim of what it will deliver.
orderHash builds the EIP-712 digest under the domain EIP712("AereSettlement", "1"). The contract inherits Ownable, ReentrancyGuard, and EIP712 from OpenZeppelin.
6.2 The settle() flow
settle is onlySolver (allowlist-gated) and nonReentrant. It requires equal-length arrays and a non-empty batch. For each order it:
- Checks
block.timestamp <= o.validTo(not expired). - Requires
executions[i].executedBuyAmount >= o.minBuyAmount(the user's floor is respected). - Recovers the EIP-712 signer with
ECDSA.recoverand requiressigner == o.user. - Requires the order hash is not already
filled, then marks it filled (replay protection). - Pulls
sellAmountfrom user to solver throughAereVaultRelayer.transferFromUser(users approved the relayer, not the settlement contract). - Pushes
executedBuyAmountofbuyTokenfrom solver to user viasafeTransferFrom(the solver must have approved the settlement contract for the buy token, or supply liquidity via internal coincidence-of-wants matching).
If any step in the loop reverts, the entire batch reverts, so a user can never be pulled from without receiving at least its minBuyAmount. cancelOrder lets a user mark its own order consumed on-chain; isOrderFillable is a view for open-order checks.
6.3 AereVaultRelayer and AereSolverRegistry
AereVaultRelayer follows the GPv2VaultRelayer pattern: users approve the relayer once per token (typically MaxUint256), and only the single authorised settlement address may call transferFromUser. Separating allowances from the settlement contract lets the settlement contract be upgraded without users re-approving. The owner can rotate the settlement address.
AereSolverRegistry follows GPv2AllowListAuthentication: an owner-curated isSolver allowlist with addSolver/removeSolver. Phase 1 (current) is an owner-curated allowlist; Phase 2 (not built) is intended to add permissionless bonded-solver entry with slashable AERE stake.
6.4 What settle() does and does not guarantee (critical honesty section)
On-chain guarantees that hold today:
- Atomic batch execution. No sandwich can be inserted between orders in the batch, because they share one transaction.
- Per-order limit protection. Every filled order delivers at least its signed
minBuyAmount, or the whole batch reverts. - Signature and replay safety. Each fill requires a valid EIP-712 signature from
o.user, and each order hash can be filled at most once.
What the contract does not enforce, despite the docstring's description of finding a "uniform clearing price":
- Uniform clearing price is not verified on-chain. The contract checks each order against its own
minBuyAmountonly. It does not check that all orders in a pair cleared at one common price. Uniform-price fairness is a solver behaviour, not a contract invariant. A solver could fill different users of the same pair at different effective prices as long as each clears its own floor. - No surplus capture and no protocol fee. Unlike CoW, this contract has no fee parameter and no surplus accounting. Any price improvement above
minBuyAmountaccrues wherever the solver directs it, not to users or to a protocol sink, on-chain. There is no wiring toAereSink(0x69581B86A48161b067Ff4E01544780625B231676) for MEV or surplus redistribution in this contract today. - No partial fills, no ERC-1271 signatures, no balance modes, no dynamic fees. The source explicitly states these are omitted and that audit-grade hardening is deferred to Phase 2.
The practical security posture is therefore: atomicity plus your own limit price protect you from the worst MEV, but you are trusting the permissioned solver for fair (uniform, surplus-returning) pricing above your floor. That is a meaningful and honest distinction from a fully trust-minimised CoW deployment.
6.5 Off-chain solver and relayer service (roadmap, not deployed)
The settlement-stack deployment artifact lists the operational pieces that would make this a live product, all recorded as next steps rather than done:
- Rotate the bootstrap solver to a dedicated solver address.
- Deploy an
aere-cow-solverDocker container running the default solver. - Stand up an order-book API at
api.aere.network/cowstoring open orders in a separate explorer-db schema. - Add an MEV-protected (intent) toggle to
/swap.htmlalongside the direct AereSwap mode. - Phase 2: bonded-solver registry for permissionless entry.
None of these off-chain services is confirmed deployed in the repository artifacts. The on-chain contracts are live; the surrounding solver and order-book infrastructure is in development.
7. How the two subsystems relate
The intended composition is: encrypted mempool blinds the ordering party to order flow, and batch settlement removes the intra-batch ordering surface. In a fully integrated design, decrypted orders from an epoch would be handed to a settlement executor that clears them as a batch.
Honest current state: the two are not integrated on-chain. AereShutterMempool V2/V3 can call an optional executor.execute(uint64,uint256,bytes) on reveal, but AereSettlement exposes settle(...), not that interface, and no adapter connects them. A user today would use either the encrypted-mempool PoC or the batch-settlement stack, not a wired pipeline. Building a mempool-to-settlement executor adapter is a named roadmap item.
8. Consolidated honest limitations and security posture
- App-layer, opt-in, not base consensus. Neither subsystem changes QBFT. Validators sign classical QBFT and can still censor or reorder the underlying commit and settle transactions at the base layer. The encrypted mempool protects transaction contents from being front-run; it does not stop a proposer from censoring or reordering ciphertext-commit transactions (though reordering opaque ciphertexts yields no MEV, since the proposer cannot see what is inside). This is not enshrined PBS and not a protocol-level encrypted mempool.
- Centralised operator and validator set. Chain 2800 runs seven validators under one operator, one client (Besu). The encrypted-mempool coordinator and sequencer default to a single address (
0xbeB33D20dFBBD49eC7AC1F617667f1f02dfd6465in the PoCs). A single sequencer commits ordering. This is a trust assumption, not a decentralised guarantee. - Trusted-dealer key setup (V2/V3). The threshold master secret is Shamir-shared by a dealer in the PoC. Until a DKG replaces the dealer, one party transiently holds
s. A live product must not ship on a trusted dealer. - Keyper accountability is detection-only. Inconsistent shares can be flagged on-chain but are not economically slashed.
- Permissioned solvers, single bootstrap solver. The settlement allowlist is owner-curated with one bootstrap solver today. Permissionless bonded, slashable solver entry is unbuilt (Phase 2).
- Uniform pricing and surplus are off-chain trust. As detailed in 6.4, the settlement contract enforces atomicity and per-order floors only.
- PoC status of the encrypted mempool. V2/V3 are demonstrated but not promoted to the canonical SDK registry, not audited externally, and carry no production traffic claim. V0 is code-only.
- No external audit. The in-source audit-fix annotations reflect internal review. There is no third-party audit of these contracts.
Stating these plainly is deliberate. For a chain with thin usage and a small validator set, credibility comes from precise scoping, not from overclaiming that app-layer opt-in tooling is base-layer MEV resistance.
9. Roadmap (in development, not yet live)
- DKG for the keyper committee to remove the trusted dealer, so no party ever holds the master secret
s. - On-chain (or precompile-assisted) symmetric unmasking. The V0 source names a proposed decryption precompile at
0x102; this is a proposed, not-live capability and would need a client fork on a scratch fork, not mainnet 2800. Today unmasking is off-chain and only DK correctness is verified on-chain. - Keyper slashing built on the existing
reportInconsistentSharedetection primitive. - Mempool-to-settlement executor adapter so a decrypted epoch feeds AereSettlement as a batch (section 7).
- On-chain uniform-price verification and surplus capture in the settlement path, with surplus routed to users or to
AereSink. - Permissionless bonded-solver registry with slashable AERE stake (Phase 2 of AereSolverRegistry).
- Promotion of the encrypted-mempool contracts into the canonical SDK registry once the trusted-dealer and audit gaps close.
- Off-chain solver and order-book service deployment (aere-cow-solver,
api.aere.network/cow,/swap.htmlintent toggle). - External audit of the full anti-MEV stack.
10. Address and artifact appendix (verbatim)
CANONICAL, from aerenew/sdk-js/src/addresses.ts:
| Contract | Address |
|---|---|
| AereSettlement | 0x9C2957b1622567B4802E4AFd4c42FB2ec70dE875 |
| AereSolverRegistry | 0xDBD29332a9993d2816EF0bD240288E03a8103f3B |
| AereVaultRelayer | 0x9FCA122e87E36D7cba20DbEA7b9b7354A4Cece91 |
| AereSink (fee sink, referenced, not wired here) | 0x69581B86A48161b067Ff4E01544780625B231676 |
| Foundation (owner) | 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3 |
POC-ARTIFACT, from aerenew/contracts/deployments/ (NOT in the canonical SDK registry; treat as proof-of-concept, in-development):
| Contract | Address | Source artifact |
|---|---|---|
| AereShutterMempoolV2 | 0x135100D523edA8D0AdC70e08af905dE5042A9310 |
shutter-mempool-v2.json |
| AereShutterMempoolV3 | 0x0C0b0560fcaa534fc30D29ae1D248CC1675281df |
shutter-mempool-v3.json |
| PoC coordinator/deployer (both) | 0xbeB33D20dFBBD49eC7AC1F617667f1f02dfd6465 |
both artifacts |
| Settlement bootstrap solver | 0xE04587e0c6da6a30a24EFe7d59701A2BfFb706d9 |
settlement-stack.json |
AereShutterMempool V0 (AereShutterMempool.sol) is code and compiled artifact only, with no deployment record, and is superseded by V2/V3.
Precompile dependency: EIP-2537 BLS12-381 pairing check at address 0x0f, live on chain 2800 under the Pectra ruleset (BLS12-381 precompiles at 0x0b through 0x11).
Contract sources of record:
aerenew/contracts/contracts/mempool/AereShutterMempool.sol(V0)aerenew/contracts/contracts/mempool/AereShutterMempoolV2.solaerenew/contracts/contracts/mempool/AereShutterMempoolV3.solaerenew/contracts/contracts/dex/AereSettlement.solaerenew/contracts/contracts/dex/AereSolverRegistry.solaerenew/contracts/contracts/dex/AereVaultRelayer.sol