Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.pfbridge.xyz/llms.txt

Use this file to discover all available pages before exploring further.

ProofBridge settles cross-chain transfers entirely on-chain through four contracts deployed on each supported network. Two of these — AdManager and OrderPortal — are the contracts you interact with directly. The other two — MerkleManager and Verifier — operate in the background to record order history and validate zero-knowledge proofs.

Contracts at a glance

AdManager

Where Makers create and manage liquidity ads, lock funds against orders, and receive settlement after a successful transfer.

OrderPortal

Where Bridgers initiate cross-chain transfers by depositing source-chain tokens and creating a signed order.

MerkleManager

An append-only Merkle Mountain Range that permanently records every order hash. You never call this contract directly.

Verifier

Validates zero-knowledge proofs on-chain using the UltraHonk proving system. You never call this contract directly.

AdManager

AdManager is deployed on the destination chain — the chain where the Maker’s liquidity lives and where the Bridger’s funds will be released. As a Maker, all your day-to-day activity happens here.

What you can do

FunctionDescription
createAdPost a new liquidity advertisement with a specific token and amount.
fundAdDeposit additional tokens into an existing ad to increase available liquidity.
withdrawFromAdWithdraw unused tokens from an open ad.
closeAdPermanently close an ad and recover all remaining funds.
lockForOrderReserve liquidity against a specific EIP-712 order hash. This appends the order to the chain’s Merkle tree.
unlockSubmit a ZK proof to complete settlement. Releases the locked ad token to the Bridger’s designated recipient.
Only the relayer calls unlock on your behalf after a valid ZK proof is generated. You do not need to call it manually.

OrderPortal

OrderPortal is deployed on the source chain — the chain where a Bridger deposits the tokens they want to transfer. Bridgers interact with this contract when they create an order.

What you can do

FunctionDescription
createOrderDeposit source-chain tokens and open a cross-chain order. The order hash is appended to the chain’s Merkle tree.
unlockSubmit a ZK proof to release the deposited tokens to the Maker’s designated recipient on this chain.
As with AdManager, the relayer calls unlock on your behalf. After you create an order, the protocol handles the rest automatically.

MerkleManager

MerkleManager maintains a Poseidon2-based Merkle Mountain Range (MMR) — an append-only ledger of every order hash ever created on the chain. It is a foundational piece of the security model: a proof of deposit on Chain A must include a valid Merkle inclusion proof against Chain A’s MMR root. You do not call MerkleManager directly. AdManager and OrderPortal hold the MANAGER_ROLE permission to append hashes after each deposit or lock.

Verifier

Verifier stores the verification key on-chain and validates the UltraHonk zero-knowledge proofs submitted during settlement. It uses the BN254 elliptic curve and a keccak-based Fiat-Shamir transform for efficient on-chain verification. You do not call Verifier directly. AdManager and OrderPortal call it internally during each unlock. The Soroban side delegates the inner verification loop to the open-source rs-soroban-ultrahonk crate, which calls Soroban’s native BN254 host functions (env.crypto().bn254().g1_msm, env.crypto().bn254().pairing_check) for every elliptic-curve operation. The full implementation walkthrough — host functions, verifier pipeline, SRS, and VK immutability — lives in the Soroban verifier internals reference. The EVM side uses Ethereum’s ecMul / ecAdd / ecPairing precompiles via an auto-generated Solidity verifier (contracts/evm/src/Verifier.sol) consuming the same proof bytes against the same VK.

Deployed addresses

Canonical sources of truth: the deployment manifests at contracts/evm/deployments/11155111.json and contracts/stellar/deployments/1000001.json in the monorepo. The tables below are snapshots; if they ever drift from the manifests, the manifests win.
Chain ID: 11155111Core contracts:Bridged tokens:
TokenSymbolAddress
Wrapped XLMWXLM0xba033066076e704E50124B9cDba63EFD3dC6414c
Native Ether (sentinel)ETH0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
ProofBridge test tokenPB0x407498fD9C955bed021c03BcbB99aD514042b59B

The Order struct (EIP-712)

Every cross-chain transfer is represented as a typed EIP-712 struct. Signing this struct cryptographically binds your order to the specific chains and contracts involved — it cannot be replayed on a different chain or with a different contract. The domain separator uses:
  • Name: Proofbridge
  • Version: 1
The chain ID and contract addresses are explicit fields in the struct itself, rather than in the domain, ensuring every field is visible and auditable — and critically, ensuring both chains produce the same digest for the same order. See Order hashing for the full treatment.
Order {
  orderChainToken     // token you are depositing (source chain)
  adChainToken        // token you will receive (destination chain)
  amount              // transfer amount, in order-chain raw units
  bridger             // your address as the Bridger
  orderChainId        // source chain ID
  orderPortal         // OrderPortal contract address on the source chain
  orderRecipient      // address to receive funds on the source chain (Maker's payout)
  adChainId           // destination chain ID
  adManager           // AdManager contract address on the destination chain
  adId                // identifier of the Maker's liquidity ad
  adCreator           // Maker's address
  adRecipient         // address to receive funds on the destination chain (your payout)
  salt                // caller-controlled nonce to prevent duplicate orders
  orderDecimals       // uint8 — decimals of the order-chain token (see Decimal scaling)
  adDecimals          // uint8 — decimals of the ad-chain token
}
Never reuse a salt value. Each order must have a unique salt to produce a distinct order hash. Reusing a salt with the same parameters will cause the transaction to revert.
  • Decimal scaling — how orderDecimals / adDecimals rebase the amount across chains, and the errors that catch a mismatch.
  • Recipient address invariants — per-chain encoding rules for orderRecipient / adRecipient (EVM upper-bytes zero, Stellar Ed25519-only).
  • Off-chain signing — the TS recipe for reproducing the on-chain digest and pre-auth request hashes bit-for-bit.