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.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.
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
| Function | Description |
|---|---|
createAd | Post a new liquidity advertisement with a specific token and amount. |
fundAd | Deposit additional tokens into an existing ad to increase available liquidity. |
withdrawFromAd | Withdraw unused tokens from an open ad. |
closeAd | Permanently close an ad and recover all remaining funds. |
lockForOrder | Reserve liquidity against a specific EIP-712 order hash. This appends the order to the chain’s Merkle tree. |
unlock | Submit 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
| Function | Description |
|---|---|
createOrder | Deposit source-chain tokens and open a cross-chain order. The order hash is appended to the chain’s Merkle tree. |
unlock | Submit 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 theMANAGER_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 eachunlock.
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.- Ethereum Sepolia
- Stellar Testnet
Chain ID: 11155111Core contracts:
Bridged tokens:
| Contract | Address |
|---|---|
| Verifier | 0xdD0aF03aF86923F3c4896f5895604893281B0D23 |
| MerkleManager | 0x8316caaC87BDe7622d33a4d3A94e392dc6F5277b |
| AdManager | 0xe56bc3fE43edb738a90639695639aD0711Df65D9 |
| OrderPortal | 0xFC9e524dF436d3bA3B22C1C29058327c54B6f75d |
| wNativeToken (WETH) | 0x38F67Fb97B96988B9d5Ef3f0f9E0DB924780D1ef |
| Token | Symbol | Address |
|---|---|---|
| Wrapped XLM | WXLM | 0xba033066076e704E50124B9cDba63EFD3dC6414c |
| Native Ether (sentinel) | ETH | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE |
| ProofBridge test token | PB | 0x407498fD9C955bed021c03BcbB99aD514042b59B |
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
Related references
- Decimal scaling — how
orderDecimals/adDecimalsrebase 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.