Skip to main content
🔨 Planned for T1. Replaces the pre-authorization relayer with on-chain BLS aggregate verification and lands several defensive contract changes in the same cutover.
Phase 2 retires the manager-signing relayer — the largest live trust assumption in Phase 1. The two counterparties on a trade become the only signers gating their own settlement.

Architecture diagram

Phase 2 architecture — BLS auth, pre-auth retired

Delta from Phase 1

What changes vs Phase 1:

Pre-auth gone

_consumeAuth, managers[], requestTokens[], and the signature / authToken / timeToExpire parameters are removed from every state-changing entry point on both AdManager and OrderPortal.

BLS verification on `unlock`

Each unlock does one native pairing check (env.crypto().bls12_381().pairing_check on Soroban, BLS12_PAIRING_CHECK precompile on EVM) against the aggregated maker + bridger signature.

`BLSKeyRegistry`

New contract. Maps each wallet to a registered BLS public key, with Proof-of-Possession enforced at registration to prevent rogue-key attacks. Single key per address in T1; a multi-key upgrade lands in Phase 3.

Route commitment per ad

Every ad pins its committed_order_token at creation time. Future admin route changes don’t reach into existing ads — closes the admin-compromise → fake-token-route drain vector.

Side-bound MMR leaves

MerkleManager leaves are now poseidon2(orderHash, sideFlag), closing the X-1 attack surface where a local-chain leaf could satisfy a counterpart-chain proof.

Pause + 2-step admin

whenNotPaused guard on every state-changing entry point. Two-step admin transfer (AccessControlDefaultAdminRules on EVM, pending_admin / accept_admin on Soroban) eliminates the wrong-address transfer footgun.

What gets signed

Both parties sign the same 15-field EIP-712 OrderData struct introduced in Phase 1. The orderHash is byte-identical on both chains by construction, so one aggregated signature verifies on either side:
authMessage  = orderHash                     // EIP-712 digest of the OrderData struct
sigAggregate = sigMaker + sigBridger         // G1 point addition
pkAggregate  = pkMaker  + pkBridger          // G2 point addition

// Pairing check on each chain's `unlock`:
e(sigAggregate, G2_generator) == e(H_to_G1(orderHash), pkAggregate)
Total signatures per trade: 2 (one per user). Users sign once; the aggregate is reused at both AdManager.unlock and OrderPortal.unlock.

Curve choices

ProofBridge uses two curves, each chosen for its job:
ConcernCurveWhy
BLS signature aggregation + on-chain verificationBLS12-381Native Stellar host functions (CAP-0059), native EVM precompile (EIP-2537), 128-bit security, matches the Noir BLS library
Deposit ZK proof (MMR inclusion + nullifier)BN254UltraHonk native; auto-generated verifier (Soroban + Solidity) already deployed in Phase 1
In T1 the two curves don’t compose at the contract layer. The deposit proof and the BLS verification are independent gates on unlock. A combined proof is a long-term optimization tracked in Phase 5. T1 also ships a standalone Noir BLS auth circuit as a building block. It isn’t on the unlock path itself, but later phases use it for agent attestations and dispute evidence.

What ships next

Phase 3: AI Agents & Dispute Resolution

Soroban custom-account contracts let makers deploy AI agents under scoped policies. Order deadline field is added; cancel and arbiter-driven dispute paths handle stuck or contested orders. The BLSKeyRegistry upgrades to multi-slot for single-tx agent rotation.