aere-research/research/specs/spec-account-abstraction.md
Aere Network 4a0b48588c 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:02:30 +03:00

28 KiB

AERE Account Abstraction and Onboarding Stack

Chain: AERE Network, chain ID 2800 (0xAF0) Consensus: Hyperledger Besu QBFT, 0.5-second target blocks, sub-second finality, seven validators EVM ruleset: Pectra (Prague/Cancun) plus Fusaka (Osaka), functional parity with Ethereum mainnet Source of truth for addresses: aerenew/sdk-js/src/addresses.ts Contract source: aerenew/contracts/contracts/

This document specifies the wallet and onboarding layer of AERE: passkey smart accounts, the ERC-4337 EntryPoint, the four gasless paymasters, EIP-7702 EOA delegation, the ERC-7579 modular account line, ERC-6551 token-bound accounts, and the post-quantum smart account. It states plainly what is live on mainnet 2800 today, what is source-complete but not yet deployed, and where the current design has seams. Honesty about the seams is deliberate: this is an engineering reference, not marketing copy.


1. Substrate: what the chain gives the wallet layer

Two hardfork features do the heavy lifting for account abstraction on AERE.

RIP-7951 secp256r1 (P-256) precompile at 0x100. Fusaka activated at unix 1780220351, block 2,106,606. From that block onward the P-256 verification precompile is unconditionally present at address 0x100. It takes a 160 byte input (msgHash || r || s || x || y, five 32 byte words) and returns a 32 byte word whose low bit is set on a valid signature. Per the registry notes the fixed cost is roughly 3,450 gas, versus roughly 250,000 gas for a pure-Solidity P-256 verification. This is what makes native passkey (WebAuthn) signatures affordable to check on chain, so a user's Face ID, Touch ID, Windows Hello, Android biometric, YubiKey, or EU Digital Identity Wallet key can directly authorize account operations with no seed phrase.

EIP-7702 EOA delegation (Pectra). An existing externally owned account can sign a 7702 authorization tuple that makes its account temporarily execute a designated contract's deployed bytecode, while remaining controlled by the original secp256k1 key. AERE uses this to upgrade a plain MetaMask style EOA into a batching, session-key, passkey-capable account without moving funds to a new address.

One substrate constraint shapes the account designs below. AERE's own EntryPoint keeps a strictly sequential, single-dimension per-sender nonce in its own storage (no 2D nonce keys of the kind canonical ERC-4337 v0.7 uses for validator routing). Accounts that want to route between multiple validators therefore cannot encode the route in a nonce key, and instead route on a signature prefix byte. This is called out explicitly in the modular account (Section 6).


2. Passkey smart accounts (live)

The passkey account is a smart contract wallet whose owner set can be WebAuthn P-256 keys, plain EOA keys, or a mix. It is the production onboarding path for "no seed phrase" users.

2.1 Components and addresses

Component Address (chain 2800) Status
AereEntryPointV2 0x8D6f40598d552fF0Cb358b6012cF4227B86aF770 Live
AerePasskeyAccountFactoryV2 0x5FFa9a6487DA4641a1A1e7900ff2bD4525D34fdA Live (canonical)
AerePasskeyAccountFactory (V1) 0xfB0eF980667A79Fe1AB69c5f2d512118F1B30739 Legacy, retained for the original demo account

Source: contracts/passkey/AerePasskeyAccountV2.sol, MultiOwnable.sol, WebAuthn.sol, AerePasskeyAccountFactoryV2.sol.

2.2 WebAuthn verification (WebAuthn.sol)

WebAuthn.verify is a precompile-only port adapted from Coinbase's base-org/webauthn-sol library. Given the 32 byte challenge, a requireUV flag, the parsed WebAuthnAuth assertion, and the public key (x, y), it:

  1. Rejects malleable signatures (s > n/2, guarding against the secp256r1 curve order half).
  2. Confirms clientDataJSON contains "type":"webauthn.get" at the declared typeIndex.
  3. Reconstructs "challenge":"<base64url(challenge)>" and confirms it appears at challengeIndex, binding the signed browser payload to the on-chain challenge.
  4. Checks the authenticator data flags: User Present always, User Verified when requireUV is set (the passkey account passes requireUV = true, so a biometric or PIN gesture is required, not a bare presence tap).
  5. Computes sha256(authenticatorData || sha256(clientDataJSON)) and calls the 0x100 precompile.

The FreshCryptoLib fallback path present in the upstream library is stripped, because the precompile is guaranteed on AERE from the Fusaka block.

2.3 Ownership model (MultiOwnable.sol)

Owners are stored as raw bytes: 32 bytes for an EOA (a uint160 address left-padded, top 12 bytes must be zero) or 64 bytes for a P-256 public key (x || y). Each owner has a monotonic index that is never reused. The authorization gate is a self-call check: onlyOwner requires msg.sender == address(this). That means every owner-management action (add EOA owner, add passkey owner, remove owner) must arrive as an authenticated self-call through one of the account's execute paths. Any single registered owner can add or remove other owners, and the set can never be emptied (removeOwnerAtIndex reverts LastOwner at count 1).

This is the account's recovery model in its live form: keep at least one owner, and optionally pre-register a backup key (for example a hardware EOA) so loss of the primary passkey does not lose the account. A guardian-and-timelock recovery flow is a separate module and lives in the in-development ERC-7579 line (Section 6), not in the passkey account itself.

2.4 Authorization paths (AerePasskeyAccountV2.sol)

The account exposes three ways to authorize a call, all resolving through the same _verifyWrappedSignature routine that selects the owner by index and dispatches to ECDSA recovery (EOA owners, EIP-191 personal_sign envelope, MetaMask compatible) or WebAuthn (passkey owners):

  • ERC-4337 path. validateUserOp is callable only by the account's entryPoint. It verifies the wrapped signature over userOpHash, returns 0 on success or 1 (SIG_VALIDATION_FAILED) on failure per spec (it does not revert on a bad signature), and forwards any missingAccountFunds prefund to the EntryPoint. Execution is dispatched by executeFromEntryPoint / executeBatchFromEntryPoint, both EntryPoint-gated.
  • Direct passkey path. executeWithPasskey / executeBatchWithPasskey let the Foundation relayer (or the user self-relaying) drive the account without a bundler. The signer signs a domain-separated getExecuteChallenge that binds address(this), block.chainid, a monotonic passkeyNonce, and the call payload, giving replay protection independent of the EntryPoint nonce.
  • EIP-1271. isValidSignature wraps the queried hash in an AereAccount1271(address account,uint256 chainid,bytes32 hash) digest before verifying, preventing cross-account signature replay. This makes the account usable with Permit2, OpenSea, Snapshot, and dapp login flows.

2.5 Deployment (AerePasskeyAccountFactoryV2.sol)

A CREATE2 factory. predictAddress(initialOwners[], salt) returns the counterfactual address; the initial owner set is mixed into the salt, so the same passkey with a different initial owner set produces a different address and multi-owner accounts cannot be front-run at their counterfactual address. createAccount is idempotent (returns the existing account if already deployed) and pins every new account to the factory's immutable defaultEntryPoint.


3. ERC-4337 EntryPoint (live) and an honest note on two EntryPoints

AERE ships two EntryPoint contracts, and the distinction matters for anyone integrating.

AereEntryPointV2 at 0x8D6f40598d552fF0Cb358b6012cF4227B86aF770 (source contracts/passkey/AereEntryPointV2.sol) is the account-facing EntryPoint. It implements the canonical handleOps(PackedUserOperation[], beneficiary) flow: a validation phase that calls account.validateUserOp for every op and reverts the whole batch on any non-zero return, then an execution phase that calls sender.call(op.callData), meters gas, and charges the paymaster's deposit if paymasterAndData names one, else the account's own deposit. It computes the canonical v0.7 userOpHash (binding the op fields, address(this), and block.chainid), keeps per-account deposits, and emits standard UserOperationEvent records so bundlers and indexers can subscribe. AERE hosts its own relayer while bootstrapping; the contract is shaped so external bundlers (Pimlico, Stackup, ZeroDev) can target it via per-chain config.

AereEntryPoint at 0x19773ba45287A64B05d0BCBD59D1371BF51Bd5D2 (source contracts/paymaster/AereEntryPoint.sol) is a lightweight, paymaster-oriented EntryPoint from the Tier-1.3 stack. It implements the deposit and stake surface (depositTo, balanceOf, withdrawTo, addStake, unlockStake, withdrawStake) plus a relayUserOp that calls a paymaster's validatePaymasterUserOp, executes the sender call, and deducts the paymaster's deposit.

Two honest consequences of this split:

  1. The four paymasters bind to the staking-capable EntryPoint interface. PaymasterBase (Section 4) declares an IEntryPoint with addStake / unlockStake / withdrawStake. AereEntryPointV2 exposes deposit accounting but not staking, whereas the lightweight AereEntryPoint implements the full stake surface. The paymaster validation hook (validatePaymasterUserOp) is therefore exercised through the lightweight EntryPoint's relayUserOp path or through an off-chain relayer that calls the hook directly.

  2. AereEntryPointV2.handleOps charges a paymaster's deposit but does not itself call validatePaymasterUserOp. It reads the paymaster address from paymasterAndData[0:20] and debits that deposit for actualGasUsed * maxFee, but the paymaster's own policy checks (per-sender caps, token pull, quota) are not invoked inside handleOps. Unifying paymaster validation into handleOps (so a single EntryPoint runs both account and paymaster validation in one batch) is a roadmap item. Until then, gasless sponsorship runs through the relayer-plus-lightweight-EntryPoint path where the hook is actually called.

Also note handleOps charges actualGasUsed * maxFee (the max fee, not an effective basefee-plus-tip price) and does not implement the full canonical prefund-and-refund economics. It is a compatible subset sufficient for the hosted relayer, not a byte-for-byte reimplementation of eth-infinitism v0.7.


4. The four gasless paymasters (live)

All four inherit PaymasterBase (contracts/paymaster/PaymasterBase.sol), an in-house Ownable (OpenZeppelin v4.9) base that exposes validatePaymasterUserOp / postOp guarded by onlyEntryPoint, plus deposit and stake helpers. Each paymaster overrides _validatePaymasterUserOp with its own sponsorship policy. "Gasless" here means the user needs no native AERE: either the Foundation, a dApp, the user's stake, or an ERC-20 covers the gas.

4.1 Address map

Paymaster Address (chain 2800) Status
AereOnboardingPaymaster 0x4058E406475Dbed7056Aee0c808f293F05fEa879 Live
AereAppPaymasterFactory 0xEC22603E8712cBc5c31E53370D10f1a80CcB4DF0 Live (permissionless factory)
AereTokenPaymasterV2 0x217f56a5b0C7f35abe4D2fff924A6c13B85d7243 Live (canonical)
AereStakeQuotaPaymasterV2 0xE50464ca7E8E7F542D1816B3172a2330cFE384E8 Live (canonical)
AereTokenPaymaster (V1) 0xEb6e2Eb24e597C85392DdCD68a1F9b654FffdcB2 Deprecated, do not use
AereStakeQuotaPaymaster (V1) 0xD16C86D792444c2667A26dB62f01b90FC0DaB87b Deprecated, do not use

4.2 AereOnboardingPaymaster (Foundation-funded)

The first-touch paymaster. It sponsors a hard-capped number of UserOps per address (sponsoredOpsPerSender, default 3, lifetime, never resets) under a sitewide per-UTC-day cap (dailySitewideCap, default 100) for Sybil resistance, with an optional target-contract whitelist. When its Foundation-funded balance drains it refuses all ops until a governance top-up. The design intent recorded in source is that 3 sponsored ops per address plus a sitewide daily cap lets a fixed, small AERE budget onboard a large number of first-time users without an automated refill.

4.3 AereAppPaymaster via AereAppPaymasterFactory (dApp-funded)

Any dApp calls createPaymaster() on the factory (no fee, permissionless) and becomes owner of its own AereAppPaymaster. The dApp funds it from its own treasury and sets a required target whitelist, an optional sender allowlist, and an optional per-sender lifetime cap. The Foundation contributes nothing. This is the standard pattern for a game, marketplace, or app to sponsor its own users' gas.

4.4 AereTokenPaymasterV2 (pay gas in an ERC-20)

Lets a user pay for gas in any whitelisted ERC-20 rather than native AERE. It reads the token's USD price and the AERE/USD price from an oracle, converts the op's AERE cost to a token amount, applies a markup in basis points (markupBps, default 500 = 5%, capped at 3000), and pulls the tokens via transferFrom (the user pre-approves). V2 fixes a V1 medium-severity bug: V1's withdrawToken used transferFrom(address(this), ...), which needs a self-allowance that never exists, permanently stranding collected token revenue; V2 uses transfer, the correct primitive for moving the contract's own balance, so the Foundation can sweep collected fees. Honest dependency: the paymaster's oracle reference is immutable and, per the registry, currently resolves to the legacy price source; repointing it to AereOracleV2 requires a fresh paymaster deploy.

4.5 AereStakeQuotaPaymasterV2 (stake AERE, get free transactions)

A Tron-style UX: a user's effective AERE stake buys a daily quota of sponsored UserOps (quotaPerDay = stakedAERE * txPerKiloAerePerDay / 1000, default 20 free ops per 1000 AERE staked, resetting each UTC day, no rollover). Effective stake is the sum of delegated stake across the validator set, the user's own validator self-stake, and active locked-staking positions. V2 fixes two confirmed high-severity liveness bugs in V1: V1 called a non-existent balanceOf on the real staking contract (so the delegated read always returned 0), and V1 decoded AereLockedStaking.getLock with the wrong field order (so any real lock hard-reverted validation and the user could never be sponsored). V2 reads the real public getters and aggregates them, matches the real getLock field order (amount first), bounds both scan loops at 100 entries so validation cannot be griefed out of gas, and wraps every external read in try/catch so a paused source degrades the quota to 0 rather than bricking validation. It reads the canonical AereStakingV2 (0x1D95eF6D17aeAB732dF914Ba2d018c270BC155FC) and AereLockedStaking (0x21108c28A849b05aE6b7a3a5bc435C9Bc897E7Ad) getters.


5. EIP-7702 EOA delegation (live)

For users who already hold a MetaMask style EOA and do not want a new address, EIP-7702 lets that EOA point its delegation tuple at a shared implementation and gain smart-account behavior in place.

Component Address (chain 2800)
AereDelegate7702 0x5673D92080efbd0987402E9335c14200d0a5EaeF
AereDelegationRegistry 0x6c25c07D134713b6C2F8E19D807423f022903D63

AereDelegate7702 (contracts/delegation/AereDelegate7702.sol) is the code an EOA delegates to. Because EIP-7702 transmits only code, not storage, every EOA delegating to this one implementation gets independent storage at its own account, and can re-point its delegation at any time with no migration. Its surface:

  • executeBatch(Call[]): atomic multicall, authorized by the EOA's own transaction signature. The owner check is msg.sender == address(this), which under 7702 is the EOA acting on itself. A transient reentrancy guard protects the batch path.
  • executeWithPasskey(Call, P256Signature): a single call authorized by a registered WebAuthn passkey, verified through the 0x100 precompile, with a relayer paying gas. A round-3 fix binds the signed clientDataJSON to the specific call by recomputing the expected challenge keccak256(address(this), passkeyNonce, call), base64url-encoding it, and requiring the canonical "challenge":"<expected>" substring, which closes a replay hole where an unrelated WebAuthn login signature could have authorized arbitrary calls. A passkeyNonce gives replay protection.
  • addSessionKey / revokeSessionKey / executeWithSessionKey: register a scoped secondary key with an expiry and a selector allowlist for low-risk, popup-free dApp flows, plus a kill switch.
  • setPasskey(x, y): register one WebAuthn key. Phase 1 supports a single passkey; the source notes a Phase 2 extension to a MultiOwnable-style set is planned.

AereDelegationRegistry is a purely informational, permissionless index: an EOA self-registers (register()), the registry records the account's delegated code hash and timestamps, and dApps query it to render a "smart-wallet enabled" badge, discover batch-eligible EOAs, and coordinate paymaster eligibility. It holds no funds and has no authority over any account; wrong data only affects the registrant's own UX.


6. ERC-7579 modular accounts, session keys, social recovery (in development, not yet on mainnet)

A modular account line exists in source but is not present in the canonical registry (addresses.ts) and is therefore not deployed to mainnet 2800. It is documented here as the intended next-generation account, marked in-development. No mainnet address is cited because none exists yet.

Source files: contracts/modular/AereModularAccount.sol, AereModularAccountFactory.sol, AereSessionKeyValidator.sol, AereSessionKeyValidatorV2.sol, AereSocialRecoveryModule.sol.

AereModularAccount is an ERC-4337 account with ERC-7579-style pluggable modules of two types: validators (type 1, signature validation) and executors (type 2, may call executeFromExecutor and setRootOwner). It targets AereEntryPointV2 exactly, and because that EntryPoint uses a single-dimension nonce, the account routes validation on the first signature byte: 0x00 selects the root-owner ECDSA fallback (0x00 || 65-byte sig over the EIP-191 envelope), 0x01 selects an installed validator module (0x01 || 20-byte validator address || payload). Validators return the canonical 4337 validation-data packing (authorizer | validUntil<<160 | validAfter<<208); since AereEntryPointV2 reverts on any non-zero return and cannot unpack time bounds, the account unpacks the packing itself, enforces the time window against block.timestamp, and returns strictly 0 or 1. It supports execute / executeBatch, EIP-1271 with the same domain-wrapping convention as the passkey account, and root-owner rotation gated to a self-call or an installed executor.

AereSessionKeyValidator / AereSessionKeyValidatorV2 (ERC-7579 type 1) grant a session key a window (validAfter, validUntil), a per-op native value cap, and an allowlist of (target, selector) pairs, with 0x00000000 as the native-transfer sentinel. V2 is a hardened redeploy of the module logic that fixes a confirmed per-batch value-cap bypass (V1 checked each executeBatch sub-call's value independently against the per-op cap with no running sum, so a session key could move maxValuePerOp * N in one batch); V2 caps the sum of sub-call values, adds a defense-in-depth rule that a session key can never call account-admin selectors (installModule, uninstallModule, setRootOwner, execute, executeBatch) back into its own account regardless of the allowlist, and adds an optional rolling cumulative spend cap.

AereSocialRecoveryModule (ERC-7579 type 2 executor) is the guardian-based recovery the live passkey account lacks. An M-of-N guardian set, per account, drives an initiateRecovery then supportRecovery flow; after a 48 hour timelock and at least the threshold approvals, any guardian may executeRecovery, which calls account.setRootOwner. The current owner or the account can cancelRecovery at any time before execution. Guardian and threshold changes are owner-only (they require msg.sender == account).

When this line is audited and deployed, its addresses will be added to addresses.ts and this section updated to "live".


7. ERC-6551 token-bound accounts (live)

ERC-6551 gives every NFT its own wallet. These are account and registry primitives, not tokens: they mint nothing and have no supply.

Component Address (chain 2800)
ERC6551Registry 0x7fFdA0AcDeB919938dB91dbEa779D841c833EF68
AereTokenBoundAccount 0xBc5e24180f3F75DC6b1965E4aaD3D4F184b6F9E2

ERC6551Registry (contracts/tokenbound/ERC6551Registry.sol) is the verbatim erc6551/reference registry: a stateless, owner-less CREATE2 factory that deploys deterministic ERC-1167 minimal-proxy accounts bound to a (chainId, tokenContract, tokenId) tuple. The source notes the canonical public deployment lives at 0x000000006551c19487814612e58FE06813775758 on chains that received the deterministic Nick-factory deploy; on AERE the identical source was deployed at the address above (the address differs only because the deterministic factory salt was not replayed here, the bytecode and behavior are identical).

AereTokenBoundAccount (contracts/tokenbound/AereTokenBoundAccount.sol) is the implementation the proxies point at. Its sole authority source is ownerOf(tokenId) on the bound ERC-721, read live. Whoever holds the NFT controls the account: they can execute arbitrary calls (operation 0, CALL only; DELEGATECALL and CREATE are rejected so the account can never be hijacked into changing its own logic), and the account produces EIP-1271 signatures on their behalf via OpenZeppelin SignatureChecker (so both EOA and smart-contract holders work). It also implements the ERC-4337 path against AereEntryPointV2 (hardcoded as ENTRY_POINT), so a bundler or paymaster can sponsor the NFT wallet's gas. A live demo binds AereNFT (0x3f9A9D9CAB005327869396C69bE226ef98039f1c) token #1 to account 0x82D24cC4E09CaBfD9B00233438B8B6321CBC13Dd.


8. Post-quantum smart account (live, roadmap #270)

The most experimental account in the stack, and the one whose scope needs the most careful statement. It is a working ERC-4337 v0.7 account whose sole owner is a NIST Falcon-512 lattice public key, with no classical ECDSA fallback.

Component Address (chain 2800)
AerePQCAccountFactory 0xd5315Ea7caa60d320c4f34b1bEd70dd9cc02CE58
AerePQCAccount_sample 0xa42a5e7F72E46BadC11367650Ec34D676194326f
AereFalcon512Verifier 0x4E8e9682329e646784fB3bd01430aA4bA54D8fFC

AerePQCAccount (contracts/pqc/AerePQCAccount.sol) owns exactly one Falcon-512 public key (897 bytes, NIST encoding, header byte 0x09). Every authorization, a bundled UserOperation, an EIP-1271 check, or the direct executeWithFalcon path, is decided by the live on-chain AereFalcon512Verifier, which runs real lattice cryptography: SHAKE256 HashToPoint, 14-bit public-key decode, compressed-signature decode, negacyclic NTT multiply mod q=12289 in the ring, centering, and an l2-norm bound check. The signature envelope is abi.encode(bytes nonce, bytes compSig) (the 40-byte Falcon salt and the compressed s2 body); the message handed to the verifier is the raw 32 bytes of the relevant hash, which for a UserOperation is the userOpHash that already binds sender and chain. validateUserOp returns 0 or 1 per spec; isValidSignature is a view, so integrators can verify a post-quantum signature for free via eth_call. AerePQCAccountFactory is a CREATE2 factory keyed on (falconPubKey, salt), mirroring the passkey factory, binding each account to an immutable EntryPoint and Falcon verifier.

Honest scope, stated exactly as the registry frames it. This is Falcon-512 (NIST security level 1), not Falcon-1024. A Falcon-512 verify is heavy: roughly 10.5M gas per PQC authorization. That is real and it fits under the Fusaka EIP-7825 per-transaction cap of 2^24 = 16,777,216 gas, and a full UserOperation through AereEntryPointV2.handleOps was demonstrated end-to-end with estimated 10,641,716 and measured 10,278,313 gas used, under the cap, opSuccess=true. A native SHAKE or keccak precompile would cut this sharply and is tracked as a separate roadmap item. PQC authorization here is app-layer and account-layer: it secures how this account authorizes operations. It does not change consensus. AERE's validators sign classical QBFT, and the native PQC precompiles that would make lattice verification cheap are proposed and in development on a scratch fork, not live on mainnet 2800. On the broader PQC verifier suite that this account draws on, we are not aware of any other public chain that verifies all of these on-chain; that is the claim, stated with that exact hedge, and nothing stronger.


9. Honest limitations

This layer is real and on chain, but a credible reader should weigh it against the following, all true today.

  • Decentralization. AERE runs seven QBFT validators under one operator, one client (Besu), with no external security audit of these contracts and thin real-world usage. The wallet layer inherits that trust profile. Sponsorship and relaying currently depend on a Foundation-hosted relayer.
  • Two EntryPoints, one seam. As described in Section 3, the account-facing AereEntryPointV2 and the paymaster-facing lightweight AereEntryPoint are distinct, and handleOps charges but does not itself invoke the paymaster validation hook. Gasless flows run through the relayer-plus-lightweight-EntryPoint path. Unifying the two is a roadmap item.
  • EntryPoint economics are a subset. AereEntryPointV2 uses maxFee for gas charging and does not implement full canonical prefund-and-refund. It is sufficient for the hosted relayer, not a drop-in reimplementation of eth-infinitism v0.7.
  • Recovery. The live passkey account's recovery is "keep at least one owner / add a backup owner". Guardian-and-timelock social recovery is source-complete in the ERC-7579 line but not yet deployed (Section 6).
  • ERC-7579 modular line is not live. The modular account, its factory, both session-key validators, and the social recovery module are in-development. They carry no mainnet address and must not be presented as deployed.
  • Post-quantum cost. The Falcon-512 account is genuinely quantum-resistant at the account layer but costs roughly 10.5M gas per authorization and is level 1, not 1024. It is a real primitive with a heavy price, pending a SHAKE precompile.
  • Deprecated contracts remain on chain. The V1 token and stake-quota paymasters, and the V1 passkey factory, are retained at their addresses; integrators must point at the canonical V2 addresses listed above.

10. Address appendix (verbatim from addresses.ts)

EntryPoints

  • AereEntryPointV2 (accounts): 0x8D6f40598d552fF0Cb358b6012cF4227B86aF770
  • AereEntryPoint (lightweight, paymaster relay): 0x19773ba45287A64B05d0BCBD59D1371BF51Bd5D2

Passkey wallets

  • AerePasskeyAccountFactoryV2: 0x5FFa9a6487DA4641a1A1e7900ff2bD4525D34fdA
  • AerePasskeyAccountFactory (V1, legacy): 0xfB0eF980667A79Fe1AB69c5f2d512118F1B30739

Paymasters

  • AereOnboardingPaymaster: 0x4058E406475Dbed7056Aee0c808f293F05fEa879
  • AereAppPaymasterFactory: 0xEC22603E8712cBc5c31E53370D10f1a80CcB4DF0
  • AereTokenPaymasterV2: 0x217f56a5b0C7f35abe4D2fff924A6c13B85d7243
  • AereStakeQuotaPaymasterV2: 0xE50464ca7E8E7F542D1816B3172a2330cFE384E8
  • AereTokenPaymaster (V1, deprecated): 0xEb6e2Eb24e597C85392DdCD68a1F9b654FffdcB2
  • AereStakeQuotaPaymaster (V1, deprecated): 0xD16C86D792444c2667A26dB62f01b90FC0DaB87b

EIP-7702

  • AereDelegate7702: 0x5673D92080efbd0987402E9335c14200d0a5EaeF
  • AereDelegationRegistry: 0x6c25c07D134713b6C2F8E19D807423f022903D63

ERC-6551

  • ERC6551Registry: 0x7fFdA0AcDeB919938dB91dbEa779D841c833EF68
  • AereTokenBoundAccount: 0xBc5e24180f3F75DC6b1965E4aaD3D4F184b6F9E2
  • Demo NFT (AereNFT): 0x3f9A9D9CAB005327869396C69bE226ef98039f1c
  • Demo bound account: 0x82D24cC4E09CaBfD9B00233438B8B6321CBC13Dd

Post-quantum account

  • AerePQCAccountFactory: 0xd5315Ea7caa60d320c4f34b1bEd70dd9cc02CE58
  • AerePQCAccount_sample: 0xa42a5e7F72E46BadC11367650Ec34D676194326f
  • AereFalcon512Verifier: 0x4E8e9682329e646784fB3bd01430aA4bA54D8fFC

Supporting

  • AereStakingV2: 0x1D95eF6D17aeAB732dF914Ba2d018c270BC155FC
  • AereLockedStaking: 0x21108c28A849b05aE6b7a3a5bc435C9Bc897E7Ad
  • Foundation (owner of all Ownable contracts): 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3

In development, no mainnet address (ERC-7579 modular line): AereModularAccount, AereModularAccountFactory, AereSessionKeyValidator, AereSessionKeyValidatorV2, AereSocialRecoveryModule.