355 lines
23 KiB
Markdown
355 lines
23 KiB
Markdown
# Aere Compute Market V3
|
|
|
|
> **Note added 2026-08-19.** Statements in this document that consensus on chain 2800 is (or remains) classical secp256k1 ECDSA QBFT were written before the post-quantum header anchor went live, and remain true for block-by-block finality. Since block 13,014,000 anchor blocks (every 32nd block, on every one since block 13,889,296) also carry, under the block hash, a certificate of validator Falcon-512 seals, and since 2026-08-14 a node rejects an anchor block with fewer than three valid seals (f+1 of nine; eight or nine are carried in practice). That is a post-quantum checkpoint about every 16 seconds, not a per-block quorum: the claim published on 2026-08-15 that from block 14,050,000 no block finalizes without a post-quantum quorum was wrong (the per-block rule armed at that height is retired in the shipped code in favour of the anchor rules) and was withdrawn on 2026-08-19. Details: https://aere.network/quantum.html and the aere-node repository, anchor/README.md.
|
|
|
|
Proof-carrying decentralized compute (DePIN) settlement for Aere Network.
|
|
|
|
## What it is
|
|
|
|
`AereComputeMarketV3` is the on-chain verification and settlement rail for a decentralized compute
|
|
marketplace. A REQUESTER posts a job (a commitment to the workload spec, a reward held in escrow, a
|
|
deadline, and a required verification mode). A PROVIDER claims the job, runs the work off-chain, and
|
|
submits a result. The provider is paid only against verifiable evidence, never on trust alone. Which
|
|
evidence counts, and when payment releases, is decided by the job's VERIFICATION MODE.
|
|
|
|
V3 unifies the verification rails that were split across the earlier coordination layer
|
|
(`AereComputeMarketV2`, which offered a single optimistic path with Foundation arbitration) and adds a
|
|
post-quantum settlement gate. The deployed V1 and V2 DePIN contracts are untouched; V3 is a new,
|
|
independent contract.
|
|
|
|
Source: `aere-contracts/contracts/depin/AereComputeMarketV3.sol`
|
|
Tests:
|
|
- `aere-contracts/test/AereComputeMarketV3.test.js` (14 cases: safety, "nobody is paid without evidence")
|
|
- `aerenew/contracts/test/AereComputeMarketV3.liveness.test.js` (14 cases: liveness and griefing,
|
|
"no single party can freeze the escrow")
|
|
- `aere-research/formal-consensus/computemarket_smt.py` (z3 model of the escrow-solvency invariant)
|
|
|
|
MEASURED 2026-07-20, `npx hardhat test aere-contracts/test/AereComputeMarketV3.test.js test/AereComputeMarketV3.liveness.test.js`
|
|
-> `28 passing (7s)`, 0 failing.
|
|
|
|
## The three verification modes
|
|
|
|
A requester picks one mode per job. Each mode answers one question: what makes a submitted result
|
|
payable?
|
|
|
|
### REPLAY (mode 0)
|
|
|
|
The result is a deterministic function of the input. On submission the provider posts the full result
|
|
bytes, which the contract emits (and anchors as `keccak256(result)`), so any watcher can re-run the
|
|
spec locally and compare `keccak256(localResult)` against the on-chain `resultHash`. The result is
|
|
accepted after a challenge window unless a challenger posts a matching bond and disputes. On a dispute
|
|
the challenger records the `resultHash` they recomputed, so the arbiter (and any observer) can
|
|
mechanically verify who is correct. The arbiter then resolves.
|
|
|
|
When to use it. Workloads that are pure, deterministic, and cheap to re-execute (batch transforms,
|
|
deterministic simulations, reproducible builds). Disputes are objectively decidable by re-running, so
|
|
the arbiter's role is mechanical rather than judgemental.
|
|
|
|
### ZK_VERIFIED (mode 1)
|
|
|
|
The result carries a zero-knowledge proof, verified ON-CHAIN through the existing deployed SP1 gateway
|
|
verifier. The provider submits the SP1 public values (ABI-encoded as `(bytes32 specHash, bytes32
|
|
resultHash)`) and the proof. The contract binds the proof to the job by requiring the proven `specHash`
|
|
to equal the job's committed spec, records the proven `resultHash`, then calls the gateway's
|
|
`verifyProof`. The reward releases in the SAME transaction, and ONLY if the proof verifies. There is no
|
|
other code path that pays a `ZK_VERIFIED` job, so paying one without a valid proof is impossible.
|
|
|
|
When to use it. Workloads where correctness must be enforced without trusting a challenge window or an
|
|
arbiter: verifiable inference, zk coprocessing, anything where the requester wants finality on delivery
|
|
rather than after a delay. The cost is that the provider must run a real prover.
|
|
|
|
The verifier reference. V3 calls the `ISP1Verifier` interface
|
|
(`aere-contracts/contracts/zkverify/ISP1Verifier.sol`), the same interface implemented by the
|
|
deployed `SP1VerifierGateway` at `0x9ca479C8c52C0EbB4599319a36a5a017BCC70628` on Aere Network chain
|
|
2800. V3 does not reimplement proof verification; it references and calls the existing gateway. The
|
|
gateway routes on the proof's first four bytes to the correct SP1 verifier and reverts on an invalid
|
|
proof, which is exactly the fail-closed behavior V3 relies on.
|
|
|
|
### OPTIMISTIC (mode 2)
|
|
|
|
The result is accepted after a challenge window unless a challenger posts a bond and disputes. A
|
|
successful dispute slashes the PROVIDER bond to the CHALLENGER and refunds the reward to the requester.
|
|
Unlike REPLAY, the result is not assumed cheaply re-derivable, so the provider stakes a bond as skin in
|
|
the game and the challenge is a general fraud claim rather than a mechanical recomputation.
|
|
|
|
When to use it. Workloads that are checkable but not cheaply reproducible (large or non-deterministic
|
|
pipelines, results that are expensive to recompute but easy to spot-check). The bond sizes the cost of
|
|
lying.
|
|
|
|
## Post-quantum settlement path
|
|
|
|
Any job in any mode can set `pqcSettlement = true`. When set, the final release of funds additionally
|
|
requires a Falcon-512 signature over a domain-separated settlement digest binding `(chainId, contract,
|
|
jobId, provider, token, amount, resultHash)`. The signature is verified IN FULL on-chain by the live
|
|
native precompile at `0x0AE1` (activated on Aere mainnet 2800 at block 9,189,161), using the same input
|
|
encoding proven against the live precompile in `AerePQCMessageVerifier`.
|
|
|
|
### Whose key, and why it matters
|
|
|
|
The settlement key is the PROVIDER's, and the provider registers it when it claims the job. This is the
|
|
single most consequential design decision in the PQC path, so it is worth stating why.
|
|
|
|
The property being bought is: a quantum adversary who has broken the provider's classical secp256k1
|
|
identity still cannot make this contract pay out that provider's earnings, because the payout also
|
|
needs a Falcon private key that Shor's algorithm does not reach. That hardens the highest-value
|
|
authorization in the system, which is the one that moves money to a new owner.
|
|
|
|
Binding the key to the REQUESTER instead would have been actively harmful. The requester would gain a
|
|
permanent veto over paying for correct work: it could simply never sign, and the provider could never
|
|
be paid. That converts a solved failure mode (a permissionless `finalize` means the buyer's cooperation
|
|
is never required) back into an unsolved one. An earlier revision of this contract had the key on the
|
|
requester; it was moved to the provider precisely because of this.
|
|
|
|
### Where PQC is deliberately NOT used
|
|
|
|
Posting, claiming, submitting, disputing and arbitration are all plain ECDSA, on purpose.
|
|
|
|
None of those operations move value to a new owner. The worst a forged claim or submission achieves is
|
|
the loss of the forger's own bond. Disputes are adjudicated on evidence (a recomputed result hash),
|
|
not on who signed the challenge. Adding Falcon signatures to those paths would cost calldata and gas
|
|
and buy no additional guarantee. A design that reaches for post-quantum signatures on every entrypoint
|
|
is marketing, not engineering, so this one does not.
|
|
|
|
### Two scope boundaries, stated plainly
|
|
|
|
CONSENSUS IS NOT POST-QUANTUM. Aere consensus is classical secp256k1 ECDSA QBFT. Blocks are produced
|
|
and sealed by classical validator signatures. The post-quantum material in this contract is at the
|
|
signature and settlement layer only. Nothing here changes block production.
|
|
|
|
THE ZK PROOFS ARE NOT POST-QUANTUM. The SP1 gateway verifies Groth16/PLONK proofs over the BN254
|
|
pairing curve. BN254 security rests on the hardness of discrete logarithms, which Shor's algorithm
|
|
breaks. A `ZK_VERIFIED` job's proof is therefore CLASSICAL and Shor-breakable, and the on-chain
|
|
verifier is a classical verifier.
|
|
|
|
The consequence is specific and should not be glossed: setting `pqcSettlement = true` on a
|
|
`ZK_VERIFIED` job hardens WHO MAY RECEIVE the payout. It does NOT make the correctness proof
|
|
quantum-safe. Against an adversary with a cryptographically relevant quantum computer, that adversary
|
|
could forge a BN254 proof for a false result, and the Falcon gate would then faithfully authorize
|
|
payment for provably-wrong work to the legitimate provider key. The combination reads stronger than it
|
|
is, which is exactly why it is written out here rather than left implicit.
|
|
|
|
If you need post-quantum correctness rather than post-quantum payout authorization, the honest answer
|
|
today is REPLAY mode, whose security rests on keccak256 (a hash, with only a Grover square-root
|
|
speedup, not a Shor break) plus the ability of any watcher to re-execute.
|
|
|
|
## Escrow-solvency guarantee
|
|
|
|
The contract tracks `totalLiabilities[token]` for every asset: the sum of open job rewards plus posted
|
|
bonds in that asset. Every escrow or bond increments it; every payout, refund, or slash decrements it by
|
|
the same amount, with effects applied before transfers. The invariant
|
|
|
|
```
|
|
balanceOf(contract, token) >= totalLiabilities[token] for every asset
|
|
```
|
|
|
|
therefore holds at all times, where `token == address(0)` is native AERE. The public view `isSolvent`
|
|
checks it. Rewards settle in native AERE or an allowlisted ERC-20; provider and challenger bonds are
|
|
always native AERE, so solvency is tracked per asset. Fee-on-transfer or rebasing reward tokens are
|
|
rejected at escrow time (the contract requires the received amount to equal the stated reward).
|
|
|
|
The test asserts `isSolvent` (and the raw balance-versus-liability comparison) after every mutating step
|
|
of every scenario, including a mixed batch of jobs across all three modes carried to their terminal
|
|
states.
|
|
|
|
## Fail-closed properties
|
|
|
|
- No double-pay. Every job reaches a terminal status (`Paid`, `Refunded`, `Slashed`) exactly once. All
|
|
fund-moving entrypoints are reentrancy-guarded and set the terminal status before any transfer.
|
|
- No pay-without-proof in ZK_VERIFIED. Settlement happens inside `submitResultZK`, after the gateway
|
|
`verifyProof` call. An invalid proof reverts the whole transaction.
|
|
- No admin drain. There is no owner and no sweep. The arbiter can only route a DISPUTED job's escrow
|
|
between its requester, provider, and challenger. Governance can only flip a token allowlist boolean.
|
|
Neither can withdraw escrowed funds.
|
|
- Deadlines. A claimed job that misses its deadline without a submission lets the requester reclaim the
|
|
reward and slashes the provider bond to the requester.
|
|
|
|
## Failure modes
|
|
|
|
A marketplace that only works when everyone behaves is not a marketplace. These are the ways this one
|
|
is attacked, and what happens in each case. Each has a test in
|
|
`test/AereComputeMarketV3.liveness.test.js` unless marked otherwise.
|
|
|
|
### The provider takes the job and vanishes
|
|
|
|
The provider posts a bond to claim. If the deadline passes with no submission, `reclaimExpired` returns
|
|
the reward to the requester AND slashes the provider's bond to the requester. Vanishing is strictly
|
|
loss-making, and the requester is compensated for the wasted deadline. A late submission is refused.
|
|
|
|
Residual risk: a provider can still grief by claiming jobs it never intends to run, burning the
|
|
requester's time until each deadline expires. The bond prices this but does not prevent it. A
|
|
reputation layer or a per-provider claim limit would; neither is in V3.
|
|
|
|
### The buyer refuses to acknowledge correct work
|
|
|
|
Fully solved for non-PQC jobs, and it is the reason `finalize` exists. Once the challenge window
|
|
closes, `finalize` is PERMISSIONLESS: any address, including the provider itself or an unrelated
|
|
bystander, can call it and the reward is released. The requester's cooperation is never required and
|
|
the requester has no veto. `acceptResult` exists only as an early-release convenience.
|
|
|
|
For a PQC job the same holds, because the required signature is the PROVIDER's, not the requester's.
|
|
The requester still cannot block payment. This is the direct payoff of that key-ownership decision.
|
|
|
|
### The provider never produces its Falcon authorization
|
|
|
|
A PQC job can only be paid with the provider's Falcon signature. If the provider loses the key or
|
|
simply stops, the reward would sit in escrow forever. `reclaimUnsettled` closes this: after the
|
|
challenge window plus `PQC_SETTLEMENT_GRACE` (7 days), the requester reclaims the reward and the
|
|
provider's bond is RETURNED to the provider, not slashed.
|
|
|
|
The bond is returned deliberately. Failing to sign is not proven fraud, so slashing would punish what
|
|
may be simple key loss. The provider forfeits the reward, which puts the entire cost of silence on the
|
|
only party that holds the key and wants the money. Before the grace period elapses this path reverts,
|
|
so a requester cannot use it to dodge paying for correct work.
|
|
|
|
### The arbiter never resolves a dispute
|
|
|
|
This was the worst hole in the design, and it is worth being blunt: an arbitrated escrow whose arbiter
|
|
goes offline, is coerced, or is censored freezes the reward AND both bonds permanently, with no
|
|
recovery. `resolveByTimeout` closes it. After `ARBITRATION_TIMEOUT` (14 days) ANY address can unwind a
|
|
stale dispute NEUTRALLY: the reward returns to the requester, and both bonds return to their posters.
|
|
|
|
Nothing is slashed, because nothing was adjudicated. An absent arbiter must not be able to enrich
|
|
either side by doing nothing, since otherwise "make the arbiter unavailable" becomes a strategy. The
|
|
z3 model carries a negative control showing that a timeout unwind which tries to pick a winner
|
|
under-backs the escrow.
|
|
|
|
Residual risk: this weakens the dispute system into "a dispute the arbiter ignores becomes a no-sale".
|
|
A provider who did correct work and was frivolously challenged loses the reward if the arbiter never
|
|
rules. That is a real cost, accepted because permanent fund lock is worse. Arbiter liveness remains a
|
|
trust assumption; V3 bounds the damage rather than removing it.
|
|
|
|
### A challenger is right but nobody is watching
|
|
|
|
NOT SOLVED, and this is the honest weak point of both optimistic modes.
|
|
|
|
The security of REPLAY and OPTIMISTIC rests entirely on at least one honest party re-running the work
|
|
and disputing within the window. If nobody watches, a provider can submit garbage and be paid by
|
|
`finalize` with no recourse. The contract cannot manufacture a watcher.
|
|
|
|
What V3 does provide: the full result bytes are emitted on-chain for inline jobs, so watching requires
|
|
no privileged access or private data feed; and a successful challenge pays the challenger the entire
|
|
provider bond, so watching is profitable in proportion to that bond. What it does NOT provide: any
|
|
guarantee that a watcher exists, any subsidy for watching a job that turns out to be honest, or any
|
|
staking of watchers. The requester's practical defence is to be its own watcher, or to size the
|
|
challenge window long enough for a third party to act.
|
|
|
|
Requesters who cannot rely on a watcher existing should use `ZK_VERIFIED`, which needs no watcher at
|
|
all, and pay the proving cost. That is the real tradeoff between the modes.
|
|
|
|
### The job output is too large to put on chain
|
|
|
|
A 40 GB tensor checkpoint does not fit in calldata. A job can declare `offchainResult = true`, and the
|
|
provider then calls `submitResultRef(id, resultHash, uri)`: the chain stores the binding keccak256
|
|
COMMITMENT, and the URI is a retrieval hint.
|
|
|
|
DATA AVAILABILITY IS NOT SOLVED BY THIS. The contract cannot check that the URI resolves, that it keeps
|
|
resolving, or that its contents hash to `resultHash`. If the provider serves nothing, a challenger
|
|
cannot replay the work. The design's answer is that an unavailable result is indistinguishable from a
|
|
wrong one and should be disputed as such; off-chain jobs remain disputable on identical terms. That is
|
|
a coherent answer, not a complete one. Requesters who cannot tolerate it should require inline results
|
|
or `ZK_VERIFIED`.
|
|
|
|
### Other paths
|
|
|
|
- Double-pay: every job reaches a terminal status exactly once; a second payout is guard-infeasible
|
|
(proved in the z3 model; all fund-moving entrypoints are reentrancy-guarded).
|
|
- Admin drain: there is no owner and no sweep. The arbiter can only route a DISPUTED job's escrow among
|
|
that job's own requester, provider and challenger. Governance can only flip a token allowlist boolean.
|
|
- Replay of a Falcon authorization: the digest binds chainId, contract, jobId, provider, token, amount
|
|
and resultHash, so an authorization cannot be reused for another job, chain, contract, or figure.
|
|
- Fee-on-transfer or rebasing reward tokens: rejected at escrow time.
|
|
|
|
## Job lifecycle (summary)
|
|
|
|
```
|
|
postJob Open requester escrows reward (+ mode / pqc / offchain params)
|
|
claimJob Claimed provider posts the required native-AERE bond (0 for ZK) and,
|
|
for a pqc job, registers ITS OWN Falcon-512 key
|
|
submitResult Submitted REPLAY / OPTIMISTIC inline: result bytes emitted, window starts
|
|
submitResultRef Submitted REPLAY / OPTIMISTIC off-chain: (hash, URI) committed, window starts
|
|
submitResultZK Paid ZK_VERIFIED: proof verified on-chain, paid in the same tx
|
|
acceptResult Paid requester accepts a Submitted result early
|
|
finalize Paid ANYONE, after the window closes with no dispute
|
|
dispute Disputed challenger posts a matching bond within the window
|
|
resolveDispute Paid/Slashed arbiter rules; a bad result slashes the provider bond to the challenger
|
|
resolveByTimeout Refunded ANYONE, after ARBITRATION_TIMEOUT: neutral unwind of a stale dispute
|
|
reclaimUnsettled Refunded requester, after the window + PQC_SETTLEMENT_GRACE, if the provider
|
|
never produced its Falcon authorization (bond returned, not slashed)
|
|
cancelJob Refunded requester reclaims an unclaimed job's escrow
|
|
reclaimExpired Refunded requester reclaims a claimed job that blew its deadline (bond slashed)
|
|
```
|
|
|
|
Every job has an exit that no single party can block. That is the liveness claim, and each clause of it
|
|
has a test.
|
|
|
|
## What V3 does NOT solve
|
|
|
|
Stated flatly, because a design document that only lists strengths is a brochure.
|
|
|
|
1. It does not create compute supply. Real GPU and accelerator capacity, the off-chain provers, and
|
|
real SP1 proving are EXTERNAL to this contract [MEASURE]. V3 is a settlement and verification rail.
|
|
A rail with no providers is not a market, and this contract cannot make providers appear.
|
|
2. It does not guarantee a watcher exists. Both optimistic modes are only as safe as the most attentive
|
|
honest party. See the failure mode above.
|
|
3. It does not solve data availability for large outputs. `submitResultRef` commits to a hash and a
|
|
retrieval hint, nothing more.
|
|
4. It does not make ZK proofs quantum-safe. On-chain verification is classical BN254 and Shor-breakable.
|
|
5. It does not make Aere consensus post-quantum. Consensus is classical secp256k1 ECDSA QBFT.
|
|
6. It does not remove the arbiter as a trust assumption. It bounds the damage an absent arbiter can do
|
|
(14 days, then a neutral unwind), but a present and dishonest arbiter can still rule wrongly on any
|
|
dispute it resolves in time. There is no appeal, no arbiter bond, and no arbiter slashing.
|
|
7. It does not price compute, match buyers to sellers, or rank providers. There is no reputation, no
|
|
discovery, and no order book. A requester must already know which provider it wants, or accept
|
|
whoever claims first.
|
|
8. It does not prevent claim-squatting, as described above.
|
|
9. It does not verify that a job spec is meaningful, or that `specHash` corresponds to anything a
|
|
provider can actually run. The commitment is opaque to the contract by design.
|
|
10. It is not audited and not deployed.
|
|
|
|
## Honest status
|
|
|
|
- Contract: built, compiles, tested. `AereComputeMarketV3.sol` compiles under solc 0.8.23 (repo
|
|
standard). MEASURED 2026-07-20: `npx hardhat compile` printed `Compiled 1 Solidity file successfully
|
|
(evm target: paris)`; `npx hardhat test aere-contracts/test/AereComputeMarketV3.test.js
|
|
test/AereComputeMarketV3.liveness.test.js` printed `28 passing (7s)`, 0 failing.
|
|
- Formal: `aere-research/formal-consensus/computemarket_smt.py` proves the escrow-solvency invariant
|
|
inductively over the modelled transitions, including the two new exit paths, with 4 negative controls
|
|
that fire as expected. BOUNDARY: this models the DESIGN accounting, not the compiled EVM bytecode.
|
|
- ZK verification path [VERIFY]: exercised against `MockSp1Verifier`, which mirrors the deployed gateway
|
|
semantics (reverts on an invalid proof). The reference verifier is the deployed `SP1VerifierGateway`
|
|
at `0x9ca479C8c52C0EbB4599319a36a5a017BCC70628`; wiring V3 to it is a deploy-time constructor
|
|
argument. Real SP1 proving has NOT been run against V3 [MEASURE].
|
|
- Falcon settlement path [VERIFY]: exercised against `MockPQCPrecompile` at `0x0AE1`, which parses the
|
|
Falcon-512 spec offsets. Real Falcon signing has NOT been run against V3. The wire encoding is
|
|
separately KAT-proven in `AerePQCMessageVerifier` and against the live mainnet precompile. On mainnet
|
|
2800 the precompile at `0x0AE1` is live.
|
|
- DEPLOYMENT DEPENDENCY: a `pqcSettlement` job is unsettleable on any chain where `0x0AE1` is not a live
|
|
Falcon-512 precompile, because `_falconVerify` fails closed. On such a chain the escrow would only
|
|
exit via `reclaimUnsettled`. V3 must therefore be deployed on Aere mainnet 2800 (or a testnet
|
|
carrying the precompiles), not on a generic EVM chain.
|
|
- Real compute supply [MEASURE]: adoption, not code, exactly like validator decentralization.
|
|
- No new token. Rewards, escrow, bonds and payment are native AERE or an allowlisted existing ERC-20.
|
|
- NOT DEPLOYED, NOT AUDITED. Built for publication and review. Deployment is FOUNDER-GATED.
|
|
|
|
## Relationship to V1 and V2 (deployed, untouched)
|
|
|
|
| | V1 `AereComputeMarket` | V2 `AereComputeMarketV2` | V3 (this) |
|
|
|---|---|---|---|
|
|
| Address (chain 2800) | `0xf0c8178a5d9feb0f70C5f184e79edeEDaddcF350` | `0x33E3B06A7344f0B201fdD11B18bC244c84dbca32` | not deployed |
|
|
| Deployed | 2026-07-07 | 2026-07-09 | founder-gated |
|
|
| Verification | optimistic + Foundation arbitration | same, plus on-chain spec/result bytes | per-job REPLAY / ZK_VERIFIED / OPTIMISTIC |
|
|
| Provider bond | stake floor | configurable stake floor | per-job bond, slashable to challenger |
|
|
| Reward asset | native AERE | native AERE | native AERE or allowlisted ERC-20 |
|
|
| Arbiter absent | escrow locked | escrow locked | neutral unwind after 14 days |
|
|
| Large outputs | inline only | inline only | inline or (hash, URI) commitment |
|
|
| PQ payout gate | none | none | optional Falcon-512 via `0x0AE1` |
|
|
| Admin sweep | `sweepSlashPool` (Foundation) | `sweepSlashPool` (Foundation) | none |
|
|
|
|
V1 and V2 remain live and untouched. V2's real shortcoming was not that it was broken: three genuine
|
|
end-to-end settlements ran against it on mainnet on 2026-07-09 (see
|
|
`deployments/compute-market-e2e.json`, jobs 0, 1 and 2, all reaching status 5 = Paid). The shortcoming
|
|
was that verification was a single fixed optimistic path with the Foundation as arbiter, so the
|
|
guarantee was identical whether the work was cheaply replayable or needed a real proof, and an
|
|
unresponsive arbiter had no timeout. V3 makes the guarantee a per-job choice and gives every path a
|
|
bounded exit.
|