Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

How to Design a Shielded Pool for Prediction Market Liquidity

This guide details the architecture for a shielded liquidity pool that breaks the on-chain link between a user's initial deposit and final settlement in a prediction market, enhancing financial privacy.
Chainscore © 2026
introduction
ARCHITECTURE GUIDE

How to Design a Shielded Pool for Prediction Market Liquidity

A technical guide to designing privacy-preserving liquidity pools for prediction markets, focusing on zero-knowledge proofs and on-chain settlement.

A shielded pool for prediction markets is a privacy-preserving smart contract that allows users to provide liquidity anonymously. Unlike a standard Automated Market Maker (AMM), it uses zero-knowledge proofs (ZKPs) to conceal the amounts, timings, and identities associated with deposits, swaps, and withdrawals. This design addresses a critical flaw in transparent prediction markets: front-running and information leakage. When liquidity positions are public, sophisticated actors can infer market-moving information, disadvantaging regular users. A shielded pool cryptographically proves the validity of transactions without revealing their underlying data.

The core architectural components are the commitment tree, the nullifier set, and the ZK circuit. User deposits generate a cryptographic commitment (e.g., a Pedersen hash of amount and secret) stored in a Merkle tree. To withdraw or trade, a user must prove membership of this tree and generate a unique nullifier to prevent double-spending, all within a ZK-SNARK circuit. For prediction markets, the circuit logic must also verify that a trade respects the pool's constant product formula (x * y = k) and that the outcome asset (e.g., YES or NO shares for an event) is valid. Frameworks like Aztec, zkSync's ZK Stack, or Noir can be used to develop these circuits.

Integrating with a prediction market platform like Polymarket or Augur requires a secure oracle relay. The shielded pool's contract must accept verified event resolutions from a trusted oracle (e.g., Chainlink or a decentralized oracle network). Upon resolution, the circuit logic allows anonymous redemption of winning shares for the collateral asset. A key design challenge is maintaining liquidity efficiency; large anonymity sets can fragment liquidity. Implementing a shielded liquidity gauge that rewards anonymous LPs with protocol tokens (e.g., via veTokenomics) can help incentivize participation and consolidate liquidity within a single shielded pool.

prerequisites
FOUNDATIONAL CONCEPTS

Prerequisites and Required Knowledge

Before designing a shielded pool for a prediction market, you need a solid grasp of the underlying technologies. This section covers the essential knowledge required to proceed.

You must understand the core mechanics of prediction markets and automated market makers (AMMs). Prediction markets, like Polymarket or Augur, allow users to bet on event outcomes using binary shares (e.g., YES/NO tokens). Liquidity for these tokens is typically provided via a constant product AMM (like Uniswap V2), where the pool holds both outcome tokens. The key challenge is that a user's trading activity in a public pool can reveal their private beliefs or strategies, which is where zero-knowledge cryptography becomes essential for shielding.

A strong foundation in zero-knowledge proofs (ZKPs) and zk-SNARKs is non-negotiable. You should be comfortable with concepts like trusted setups, circuit compilation, and proof generation/verification. Frameworks like Circom for writing ZK circuits and snarkjs for proof management are industry standards. For a shielded pool, the circuit logic must enforce that every deposit, trade, and withdrawal maintains the correct pool reserves and user balances without revealing any linking information on-chain. Familiarity with elliptic curve cryptography, particularly the BN254 (Barreto-Naehrig) curve commonly used in Ethereum's precompiles, is also required.

Proficiency in smart contract development for Ethereum or other EVM chains is critical. The system will involve at least two contracts: a verifier contract that validates ZK proofs on-chain and a shielded pool manager that holds funds and updates state based on verified proofs. You need to understand how to handle cryptographic primitives like Poseidon hashes (common in ZK circuits for efficiency) within Solidity, manage gas optimization for proof verification, and design secure state transition logic. Experience with Foundry or Hardhat for testing complex, stateful contracts is highly recommended.

Finally, you must grasp the privacy-utility trade-offs specific to prediction markets. A fully shielded pool where all activity is private faces the liquidity fragmentation problem—it cannot interoperate with public AMM liquidity. You'll need to decide on the system's privacy model: will it shield only user identities (using stealth addresses), trade amounts, or the entire trading history? Each choice impacts circuit complexity, gas costs, and user experience. Reviewing existing designs like Tornado Cash for notes and nullifiers or Aztec Connect for private DeFi interactions will provide practical architectural insights.

core-architecture
CORE ARCHITECTURE AND SYSTEM COMPONENTS

How to Design a Shielded Pool for Prediction Market Liquidity

This guide explains the architectural components and cryptographic primitives required to build a shielded liquidity pool that protects user positions in decentralized prediction markets.

A shielded pool for prediction markets is a privacy-preserving liquidity mechanism that conceals user bets and positions. Unlike transparent Automated Market Makers (AMMs) where all trades are public on-chain, a shielded pool uses zero-knowledge proofs (ZKPs) to validate transactions without revealing underlying data. The core goal is to protect sensitive financial information—such as a user's chosen outcome, bet size, and potential profit—while maintaining the solvency and integrity of the market. This is critical for prediction markets where early position visibility can lead to front-running or market manipulation.

The system architecture relies on three key cryptographic components: a commitment scheme, a zero-knowledge proof system (like zk-SNARKs or zk-STARKs), and a nullifier scheme. When a user deposits liquidity or places a bet, they generate a cryptographic commitment (e.g., commitment = Hash(secret, amount, outcome) ) and submit it to the pool's contract. The actual details remain private. The ZKP system generates a proof that the transaction is valid (e.g., the user has sufficient funds, the bet follows market rules) without disclosing the secret inputs. This proof is verified on-chain to update the pool's state.

Managing withdrawals and preventing double-spends requires a nullifier scheme. Each deposit commitment has a corresponding nullifier—a unique identifier derived from the user's secret. When a user wants to withdraw funds or claim winnings, they present a ZKP that they know the secret for an unspent commitment and reveal the associated nullifier. The contract checks this nullifier against a spent list; if it's new, the withdrawal is processed and the nullifier is recorded, preventing the same commitment from being used again. This mirrors the nullifier mechanism in privacy systems like Tornado Cash.

For prediction markets, the pool logic must be extended to handle conditional outcomes. A smart contract must be able to settle the pool based on a verified oracle result (e.g., from Chainlink or UMA) without learning individual positions. Using ZKPs, users can claim payouts by proving their initial commitment was for the winning outcome and that the oracle result is correct. The pool's balance sheet is maintained cryptographically: the sum of all unspent commitments' values must always equal the contract's token balance, ensuring solvency can be publicly verified without exposing individual accounts.

Implementing this requires careful circuit design for the ZKP. A basic circuit for a deposit would take private inputs (secret s, amount v, outcome o) and public inputs (pool identifier). It would output the commitment C and ensure v > 0. A withdrawal circuit would take private inputs (s, v, o, oracle result r) and public inputs (nullifier N, recipient address). It would verify that C is in the pool's Merkle tree of commitments, that N = Hash(s), and that the payout is valid given o and r. Frameworks like Circom or Halo2 are used to write these constraints.

Key design considerations include the trust model for the initial setup (requiring a trusted ceremony for zk-SNARKs), gas costs of on-chain verification, and user experience in managing ZKP keys. Scalability can be addressed by using a batch processing mechanism, such as a rollup, to aggregate multiple proofs. Real-world examples exploring similar concepts include Aztec Network's private DeFi and Semaphore's anonymous signaling. By integrating these components, developers can build prediction markets where liquidity provision and trading are confidential by default.

key-concepts
DESIGN FOUNDATIONS

Key Cryptographic and Protocol Concepts

Core technical components required to build a secure and efficient shielded pool for prediction markets.

01

Zero-Knowledge Proofs for Confidentiality

Zero-knowledge proofs (ZKPs) are essential for hiding user positions and trades. Use zk-SNARKs (e.g., Groth16, Plonk) or zk-STARKs to prove the validity of transactions without revealing underlying data.

  • Application: Prove you have sufficient collateral for a trade without exposing your balance.
  • Key Choice: SNARKs require a trusted setup but are smaller and cheaper to verify. STARKs are trustless but generate larger proofs.
02

Commitment Schemes for State Management

A Merkle tree (or a Verkle tree) acts as the core data structure to commit to the state of all shielded notes. Users prove membership of their notes via Merkle proofs.

  • Note Structure: Each note = (secret key, value, asset type, prediction market ID).
  • Nullifiers: Prevent double-spending by publishing a unique, deterministic nullifier when a note is spent, without linking it to the original note.
03

Multi-Asset Shielded Pool Architecture

Prediction markets require handling multiple collateral types (e.g., ETH, USDC, specific tokens). Design a unified pool that supports confidential deposits of various assets.

  • Asset Identifiers: Use an asset_id within each note to differentiate collateral.
  • Balance Tracking: The pool's Merkle tree must commit to both the amount and type of asset for each note, enabling private cross-asset settlements.
04

Prediction Market Logic Integration

The pool must interact with an external prediction market contract (e.g., based on a conditional tokens framework). Key interactions require ZK proofs.

  • Private Position Minting: Prove you have shielded collateral to mint a prediction market position.
  • Private Settlement: Redeem winning positions back into the shielded pool without revealing which side you bet on or your profit.
05

Liquidity Provision & AMM Mechanics

To facilitate trading, integrate a constant function market maker (CFMM) within the shielded environment. This allows users to provide liquidity and swap positions confidentially.

  • Shielded LP Shares: Represent liquidity provider positions as shielded notes.
  • ZK-AMM: Swap proofs must verify the CFMM invariant (e.g., x*y=k) is maintained without revealing trade sizes or pool reserves.
06

Trusted Setup & Operational Security

If using SNARKs, a trusted setup ceremony (like Tornado Cash's or Aztec's) is a critical security dependency. For production, consider decentralized multi-party computations (MPCs).

  • Relayer Network: To preserve privacy, users can submit transactions via third-party relayers who pay gas fees.
  • View Keys: Optional feature allowing users to delegate read-access to their private balances for auditing or compliance.
deposit-mechanism
CORE CONCEPT

Step 1: Implementing the Private Deposit

The first step in building a shielded pool for prediction markets is to design a mechanism that allows users to deposit funds without revealing their identity or the amount to the public ledger.

A private deposit is the foundational privacy primitive for a shielded pool. Unlike a standard ERC-20 transfer, which broadcasts sender, recipient, and value on-chain, a private deposit must cryptographically conceal this information. The standard approach, used by protocols like Tornado Cash and Aztec, involves a commitment scheme. When a user deposits funds, they generate a secret nullifier and a commitment. The commitment, a hash of the nullifier and their public key, is published on-chain, while the nullifier is kept private. The deposited funds are locked in a smart contract, now associated only with this opaque commitment.

For a prediction market, the deposit contract must be customized to accept the market's specific liquidity token (e.g., the platform's staking or governance token). The core function, often called deposit, will require the token amount and the user-generated commitment as arguments. Crucially, the function must verify a zero-knowledge proof (ZKP) that proves the user legitimately owns the tokens and correctly computed the commitment, without revealing the linking secret. This is typically implemented using a zk-SNARK verifier contract, such as one generated by Circom or Halo2. The contract logic is: verify proof, accept tokens, and emit an event with the new commitment.

Here is a simplified Solidity interface for the deposit function:

solidity
function deposit(
    uint256 _amount,
    bytes32 _commitment,
    bytes calldata _proof
) external {
    require(_amount > 0, "Invalid amount");
    // Transfer tokens from user to contract
    token.safeTransferFrom(msg.sender, address(this), _amount);
    // Verify the zk-SNARK proof validates the commitment
    require(verifier.verifyProof(_proof, [_commitment]), "Invalid proof");
    // Insert the commitment into the Merkle tree of deposits
    deposits.insert(_commitment);
    emit Deposit(_commitment, block.timestamp);
}

The _proof argument is the zk-SNARK that attests to the correct computation of _commitment from a secret nullifier, proving the user isn't attempting to double-spend or create funds from nothing.

After a successful deposit, the commitment is inserted into a Merkle tree stored within the contract. This tree accumulates all deposits and serves as the privacy-preserving ledger. The user's ability to later withdraw their funds depends on proving membership of their commitment in this tree, which is done with a Merkle proof inside a subsequent ZKP. The security of the entire pool hinges on the soundness of the zk-SNARK circuit and the safe randomness used to generate the nullifier. A flawed circuit or a predictable nullifier can break anonymity or allow theft.

Implementing this step requires careful integration of several components: the token contract, the zk-SNARK verifier, the Merkle tree library (like Incremental Merkle Tree from Tornado Cash), and event logging. The deposit event should only emit the commitment and a timestamp; including msg.sender or _amount would leak privacy. Once this contract is deployed and tested, the pool has a functional, private intake mechanism for prediction market liquidity, setting the stage for the next step: enabling private withdrawals to any recipient.

internal-trading-mechanism
ARCHITECTURE

Step 2: Facilitating Anonymous Internal Trading

This section details the core design of a shielded pool that enables private liquidity provision and trading within a prediction market, using zero-knowledge proofs to hide user positions and balances.

A shielded pool for a prediction market acts as a private liquidity layer. Unlike a standard AMM pool where all deposits and trades are public on-chain, this pool uses cryptographic commitments to obscure user activity. Users deposit assets into the pool and receive a private commitment note (e.g., a zk-SNARK proof) representing their share and chosen market position (e.g., "YES" or "NO"). The pool's public state only shows the encrypted commitments and the total liquidity for each outcome, not individual holdings. This architecture is inspired by privacy protocols like Tornado Cash but adapted for conditional, outcome-based assets.

Internal trading within the pool is facilitated through a shielded swap mechanism. When a user wants to trade, say, "YES" shares for "NO" shares, they generate a zero-knowledge proof. This proof cryptographically validates that: 1) they own a valid input commitment for "YES" shares, 2) they are destroying those shares, 3) they are creating new, valid output commitments for the corresponding "NO" shares (and possibly change), and 4) the trade respects the pool's constant-product or other pricing curve. The smart contract verifies this proof and updates the public commitment tree, all without revealing which user traded or the exact amounts involved in their private portfolio.

The core technical components are the commitment scheme and the circuit logic. A commitment C = Hash(secret, value, outcome) binds a user's secret nullifier, deposit amount, and market position. The zk-SNARK circuit, written in a language like Circom or Halo2, encodes the trading rules. For a constant-product market maker x * y = k, where x and y are the shielded liquidity for two outcomes, the circuit ensures that for a trade of Δx, the user receives Δy calculated by the public pricing function, with all values kept private within the proof. The contract only sees the proof and the updated public k.

Managing liquidity and preventing front-running requires a commitment Merkle tree and nullifier set. Each user's deposit commitment is a leaf in a Merkle tree, with the root stored on-chain. To spend a commitment (e.g., to trade or withdraw), the user must prove its inclusion in the latest root. Once spent, the commitment's unique nullifier (derived from the user's secret) is published to a public set, preventing double-spends. This structure, combined with the privacy of zk-proofs, ensures that while the system's integrity is publicly verifiable, individual liquidity flows remain completely anonymous.

Integrating with a prediction market's resolution requires a finalization phase. When a market resolves to an outcome, the pool's internal pricing curve is fixed. Users can then generate a final withdrawal proof demonstrating they own a commitment for the winning outcome. The proof verifies the commitment's validity against the final Merkle root and that its nullifier hasn't been used. Upon verification, the contract releases the corresponding share of the pooled winnings to the user. This design allows for end-to-end anonymous participation, from providing liquidity to collecting rewards, without exposing individual bets or trading strategies to the network.

withdrawal-mechanism
IMPLEMENTING PRIVACY

Step 3: Enabling Private Withdrawal and Settlement

This step details the cryptographic mechanisms that allow users to privately withdraw funds and settle their positions from a shielded prediction market pool, ensuring transaction amounts and user identities remain confidential.

The core of a shielded pool's privacy is the zero-knowledge proof (ZKP). When a user wants to withdraw funds or settle a winning prediction, they must generate a proof, such as a zk-SNARK, that attests to two key facts without revealing the underlying data. First, the proof confirms the user possesses a valid commitment (a cryptographic note representing their deposit) that exists within the pool's Merkle tree. Second, it proves the commitment's value is greater than or equal to the requested withdrawal amount. This allows the smart contract to verify the transaction's legitimacy while learning nothing about the user's identity or the specific note being spent.

To prevent double-spending of the same commitment, the system employs a nullifier. When a commitment is spent (withdrawn or settled), a unique nullifier is published on-chain. The ZKP cryptographically links this nullifier to the spent commitment in a way that only the note's owner can generate it. The contract maintains a registry of used nullifiers and rejects any transaction that attempts to reuse one. This mechanism is privacy-preserving because the nullifier appears as a random number to observers; they cannot determine which specific commitment it corresponds to, only that some commitment has been consumed.

For prediction market settlements, the logic extends beyond simple withdrawals. A user must prove their commitment is linked to a winning outcome. This typically involves the ZPK also verifying a Merkle proof that their commitment's associated outcome hash matches the oracle-reported result for that market epoch. The contract logic then calculates the payout—often a multiple of the original stake based on pool odds—and authorizes the withdrawal of that new, private amount. All settlement calculations and value transfers occur inside the proof, keeping the user's profit completely confidential.

Implementing this requires careful smart contract design. The withdrawal/settlement function must verify the ZPK, check the nullifier, and then execute a private transfer. Using Aztec Network's Aztec.nr framework as an example, the function skeleton involves: validating the proof with context.verify_proof(), checking context.is_nullifier_revealed(), and then using context.msg_sender.transfer_public() to move funds to a public withdrawal address or context.msg_sender.transfer_private() to send to another shielded note. The user's client (wallet) handles the complex proof generation offline.

A critical consideration is withdrawal anonymity sets. Privacy weakens if only one user withdraws at a time. Best practices encourage batching mechanisms or relayers that allow multiple withdrawals to be aggregated into a single transaction. This makes it computationally infeasible for an observer to link a specific withdrawal output to a specific input commitment, as the transaction contains multiple nullifiers and output notes mixed together, significantly strengthening user privacy.

Finally, developers must design for gas efficiency and user experience. ZK proof generation can be computationally heavy for the user's device. Optimizations include using recursive proofs or proof batching. Furthermore, the system should support gasless transactions via relayers or paymasters so users aren't forced to reveal their identity by paying for gas from a public Ethereum account. The end goal is a seamless flow where users can claim winnings with the same privacy guarantees as when they initially deposited.

ARCHITECTURE

Comparison: Tornado Cash vs. Prediction Market Shielded Pool

Key design differences between a generic privacy mixer and a shielded pool built for prediction market liquidity.

FeatureTornado CashPrediction Market Pool

Primary Purpose

Generic asset anonymization

Private liquidity provision for binary outcomes

Deposit Asset

Native token (ETH, MATIC, etc.)

Conditional outcome tokens (YES/NO shares)

Anonymity Set

Global, shared across all users

Per-market, limited to participants

Withdrawal Proof

Zero-knowledge proof of deposit

ZK-proof of deposit + market resolution

Liquidity Model

Fixed pool, time-locked withdrawals

Dynamic, resolved to collateral after market close

Fee Structure

Fixed 0.3% protocol fee

Variable fee based on market volume and resolution

Trust Assumption

Trustless, cryptographic guarantees

Trust in market oracle for final resolution

Regulatory Surface

High (generic money transmission)

Lower (specific, non-fungible utility)

implementation-considerations
DESIGNING SHIELDED POOLS

Critical Implementation Considerations and Risks

Building a shielded pool for prediction markets requires balancing privacy, liquidity, and security. These cards detail the core technical challenges and mitigation strategies.

03

Managing On-Chain Data & Cost Efficiency

Zero-knowledge proof generation is computationally intensive. For a prediction market, where odds update frequently, this creates cost challenges.

  • Proof Batching: Aggregate multiple user actions (deposits, bets, withdrawals) into a single proof.
  • State Tree Design: Optimize Merkle tree depth (often 32 levels) for your target user base to balance proof cost and capacity.
  • L2 Settlement: Deploy the pool on a zkRollup (like zkSync Era) or validium to reduce data publication costs. Expect proof generation costs of $0.01-$0.10 per transaction at scale.
$0.01-$0.10
Target Tx Cost
32
Typical Tree Depth
05

Ensuring Oracle Integrity Under Privacy

Resolving prediction markets requires trusted data. A shielded pool cannot reveal user positions to the oracle without breaking privacy, yet the oracle must trigger settlements. Design Pattern: Use a discreet logging oracle. The oracle posts signed outcome results on-chain. The shielded pool's logic verifies this signature internally. Users then generate a zk-proof demonstrating they hold a note for a winning market, allowing withdrawal without revealing which specific bet they held. This decouples oracle data from user identity.

06

Smart Contract and Cryptographic Audits

The attack surface includes the pool's Solidity/Vyper contracts, the circuit logic (e.g., written in Circom or Halo2), and trusted setup ceremonies. Audit Checklist:

  • Circuit Correctness: Formal verification of zk-SNARK/STARK logic for balance integrity.
  • Nullifier Vulnerabilities: Ensure double-spend protection via nullifiers is sound.
  • Trusted Setup Participation: Use a reputable multi-party ceremony (e.g., Perpetual Powers of Tau) and consider a validity bug bounty program. A single bug can lead to complete, irreversible loss of shielded funds.
100%
Irreversible Loss Risk
SHIELDED POOLS

Frequently Asked Questions (FAQ)

Common technical questions about designing privacy-preserving liquidity pools for prediction markets, covering architecture, security, and integration.

The fundamental primitive is a zero-knowledge proof (ZKP) system, specifically a zk-SNARK (Succinct Non-Interactive Argument of Knowledge). This allows a user to prove they own a valid, unspent commitment (a note) representing liquidity or a position without revealing which specific note it is. The pool's state is typically represented as a Merkle tree of these commitments. When a user deposits or trades, they generate a ZKP that attests to:

  • Knowing the secret key for an input note in the tree.
  • The note has not been spent.
  • The transaction computes new output notes correctly (conserving value).
  • The new output commitments are inserted into the updated tree root. Protocols like zk-SNARKs (as used by Zcash's Sapling protocol) or zk-STARKs are common choices, balancing proof size, verification cost, and trust assumptions.
conclusion-next-steps
IMPLEMENTATION ROADMAP

Conclusion and Next Steps for Development

This guide has outlined the core cryptographic and architectural components for building a shielded pool for prediction markets. The next step is to implement these concepts into a functional system.

You now have the foundational blueprint for a zero-knowledge (ZK) shielded pool tailored for prediction market liquidity. The core design integrates a commitment tree (like a Merkle tree) to store encrypted user balances, a nullifier set to prevent double-spending, and a relayer network for gas abstraction. The key is to use a custom ZK-SNARK circuit that validates: a user's existing balance commitment, the correctness of a new commitment after a trade, and that the nullifier hasn't been used before, all without revealing the user's identity or trade size.

For implementation, start by selecting your proving system. Circom with the Groth16 prover is a common choice for its efficiency, but newer frameworks like Halo2 or Noir offer different trade-offs in trust setup and developer experience. Your circuit's logic must enforce the prediction market's specific rules—for example, verifying that a user's trade doesn't exceed the available liquidity for a given outcome and that the odds are calculated correctly based on the updated pool state. A reference implementation can be found in projects like Tornado Cash Nova or Aztec Protocol's zk.money, though they will require significant modification for non-fungible prediction shares.

The next phase involves building the surrounding infrastructure. You'll need: an off-chain prover service to generate ZK proofs for users, a secure multi-party computation (MPC) ceremony for a trusted setup if using Groth16, and a relayer to submit the private transactions to the blockchain. For user experience, develop a client-side SDK that handles key management (generating and storing the nullifier and secret keys) and proof generation, possibly using a WebAssembly (WASM) prover in the browser.

Finally, rigorous testing and security auditing are non-negotiable. Use formal verification tools for your circuit logic where possible. Conduct extensive audits focused on the cryptographic primitives, the circuit's constraints, and the integration points between the smart contract and off-chain components. Launching on a testnet with a bug bounty program is a critical step before mainnet deployment. The end goal is a system where liquidity providers and traders can participate with financial privacy, strengthening the censorship-resistance and integrity of the prediction market itself.

How to Design a Shielded Pool for Prediction Market Liquidity | ChainScore Guides