Skip links

Building the Oracle State Machine: L3 zk-Rollup Architecture for State Synchronization

TL;DR

Oraclizer’s L3 zk-Rollup architecture is built on Polygon CDK atop Base L2, forming a complete cryptographic finality chain extending to Ethereum L1. This article reveals key design decisions and implementation details derived from our actual development process:

  • zkProver-zkVerify Integration: 91% verification cost reduction structure leveraging Horizen Labs’ zkVerify
  • Sparse Merkle Tree Optimization: SMT-based state management and incremental update mechanisms for state synchronization efficiency
  • Validium/Volition Hybrid: Flexible data availability switching based on regulatory requirements
  • Regulatory Compliance Layer: Protocol-level regulatory control tightly integrated with the ERC-TRUST standard

While Zcash’s recent 2000% surge reflects privacy demand, Oraclizer implements auditable privacy that allows selective access by regulatory authorities—going beyond simple privacy. This is not merely technical innovation, but essential infrastructure for structural harmony between financial regulation and blockchain innovation.


Introduction: Two Visions of Zero-Knowledge Proofs

In Q3 2025, an intriguing phenomenon emerged in the privacy coin market. Zcash surpassed Monero to reclaim the #1 privacy coin position, surging over 2000% in three months. This reflects not mere speculation, but structural privacy demand growth driven by intensifying financial regulation.

However, we must ask a fundamental question: Is privacy alone sufficient?

Privacy coins like Zcash provide complete anonymity, but this structure cannot coexist with regulatory compliance. In contrast, Oraclizer utilizes zero-knowledge proof technology for an entirely different purpose. Our L3 zk-Rollup implements auditable privacy—providing privacy while allowing selective access by regulatory authorities.

This difference transcends technical choice—it’s a philosophical divergence. Zcash pursues “complete concealment,” while Oraclizer seeks coexistence of regulation and innovation through “selective disclosure.” This is not a simple privacy solution, but a fundamental redesign of the financial system.

This article reveals the actual development process and core design decisions of Oraclizer’s L3 zk-Rollup. From Polygon CDK-based implementation, Horizen zkVerify integration, Sparse Merkle Tree optimization, to regulatory compliance layer design—we share our six-month technical journey and insights.

L3 Architecture: Trust Chain from Base to Ethereum

Hierarchical Finality Model

The core of Oraclizer L3 is multi-layer finality assurance. We’re not simply stacking another layer atop Base L2, but constructing a cryptographically verifiable trust chain extending to Ethereum L1.

Oraclizer L3 (Polygon zkEVM CDK) Transaction Execution | RWA Registry | RAI System | Regulatory Actions D-quencer Sequencing zkProver (CDK) ZK Proof Generation OSS Stage 1: Parallel Processing Event Collection | External API Calls | DA Publishing Concurrent execution for maximum throughput Data Availability Split (Volition Mode) Transaction Data Distribution Avail DA (90%) Base L2 (10%) Avail DA (Off-chain) Lightweight | Low cost Off-chain TX data storage Base L2 (On-chain) Full security | Higher cost On-chain TX data storage zkVerify (Horizen Labs) Proof-agnostic verification OSS Stage 2: Sequential Validation State Transition Verification | Conflict Resolution Sequential processing ensures state consistency D-quencer Consensus BLS Signatures | VRF Leader Selection | Byzantine Fault Tolerance Finality: 1-2 seconds OSS Stage 3: Parallel Finalization Cross-chain Messages | RWA Registry Updates | Event Publishing Parallel execution for efficient state propagation Base L2 (OP Stack) State Hash Storage | Bridge Hub | Optimistic Rollup to Ethereum L1 Optimistic Proof Ethereum L1 Final Security Layer | Immutable Foundation L3 L2 L1
Oraclizer L3 (Polygon zkEVM CDK)
State Synchronization Layer
  • Transaction execution & D-quencer sequencing
  • RWA Registry & RAI System
  • 6 Regulatory Actions
  • SMT State Management
zkProver (CDK)
ZK Proof Generation
  • Generates zero-knowledge proofs for state transitions
  • Cryptographic verification data creation
OSS Stage 1: Parallel Processing
  • Event collection from multiple sources
  • External API calls (concurrent)
  • DA publishing initialization
Concurrent execution for maximum throughput
Data Availability Split
Volition Mode
  • Avail DA (90%): Off-chain transaction data storage
  • Base L2 (10%): On-chain transaction data storage
  • Flexible data availability strategy based on security requirements
zkVerify (Horizen Labs)
External Verification Service
  • Unified proof verification from both DA paths
  • Proof-agnostic architecture
  • Batch verification optimization
  • verification cost reduction
OSS Stage 2: Sequential Validation
  • State transition verification
  • Conflict resolution
  • Regulatory compliance validation
Sequential processing ensures state consistency
D-quencer Consensus
Decentralized Sequencer Consensus
  • BLS signature aggregation
  • VRF-based leader selection
  • Byzantine fault tolerance
  • Finality: 1-2 seconds
OSS Stage 3: Parallel Finalization
  • Cross-chain message transmission
  • RWA Registry updates
  • Event publishing to subscribers
Parallel execution for efficient state propagation
Base L2 (OP Stack)
Settlement Layer
  • Stores verified state hashes
  • Bridge hub for cross-chain operations
  • Optimistic rollup to Ethereum L1
  • Fast finality: 1-2 seconds
Ethereum L1
Final Security Layer
  • Ultimate finality guarantee
  • Immutable security foundation
  • Global consensus anchor
  • 7-day challenge period (from Base L2)
Figure 1: Complete L3 Architecture with OSS 3-Stage Pipeline and Hierarchical Finality

Each layer in this structure has a clear role:

  • L3 (Oraclizer): RWA state synchronization and regulatory compliance execution
  • L2 (Base): Efficient settlement and bridge hub
  • L1 (Ethereum): Ultimate security and finality guarantee

Polygon CDK-Based Implementation Decision

During the L3 solution selection process, we evaluated various options:

  • Optimism/Arbitrum Stack: Familiar but complex zk proof integration
  • zkSync Era SDK: zk-native but customization constraints
  • Polygon CDK: Optimal balance of modularity and zk proof integration

Technical reasons for choosing Polygon CDK:

  • Proven zkProver: Leverage zkEVM Prover already verified on mainnet
  • Modular Architecture: Customizable Executor, Sequencer, and Aggregator components
  • zkVerify Integration Ease: Smooth integration through collaboration with Horizen
  • Validium Support: Cost optimization via off-chain data availability

However, we don’t use CDK as-is. We’ve made modifications optimized for state synchronization requirements.

zkProver-zkVerify Integration: Structural Cost Reduction

Dual Proof Bottleneck Problem

A typical zk-Rollup has the following proof flow:

Executor → zkProver (Proof Generation) → L1 Verifier (On-chain Verification)

The problem is L1 on-chain verification cost. Each zk-SNARK verification consumes approximately 300,000 gas on Ethereum, potentially costing up to $60 per proof during high gas periods.

Our L3 structure further complicates this:

L3 zkProver → Base L2 Verification → Ethereum L1 Final Verification

If verified independently at each stage, dual verification costs occur.

Verification Offload via zkVerify

Horizen Labs’ zkVerify provides an elegant solution to this problem. zkVerify is a specialized proof verification L1 implementing the following innovations:

  • Batch Verification: Aggregate multiple proofs into one verification transaction
  • Proof-Agnostic Design: Support all proof systems including Groth16, PLONK, Halo2, STARK
  • 91% Cost Reduction: Dramatic cost decrease compared to direct Ethereum verification

Oraclizer Integration Architecture:

L3 Executor → zkProver (Proof Generation)
    ↓
zkVerify (Specialized Verification Layer)
    ↓ [Verification Completion Proof]
Base L2 (Store proof reference only)
    ↓
Ethereum L1 (Final Finality)

Actual Integration Implementation

For zkVerify integration, we modified CDK’s Aggregator component:

// zkVerify Integration Interface
type ZkVerifyClient struct {
    endpoint string
    signer   *ecdsa.PrivateKey
}

// Submit proof to zkVerify
func (c *ZkVerifyClient) SubmitProof(proof *ZkProof) (*VerificationReceipt, error) {
    // Serialize proof for zkVerify protocol
    proofData := SerializeProofForZkVerify(proof)

    // Submit to zkVerify network
    tx, err := c.submitTransaction(proofData)
    if err != nil {
        return nil, fmt.Errorf("zkVerify submission failed: %w", err)
    }

    // Wait for verification completion
    receipt, err := c.waitForVerification(tx.Hash)
    if err != nil {
        return nil, fmt.Errorf("verification timeout: %w", err)
    }

    return receipt, nil
}

// Record verification reference on Base L2
func (a *Aggregator) FinalizeOnBase(receipt *VerificationReceipt) error {
    // Record only zkVerify verification hash on Base
    calldata := abi.Pack("recordVerification", 
        receipt.ProofHash,
        receipt.ZkVerifyTxHash,
        receipt.Timestamp)

    tx, err := a.baseBridge.Call(calldata)
    if err != nil {
        return fmt.Errorf("Base settlement failed: %w", err)
    }

    log.Info("Proof verified via zkVerify", 
        "proof", receipt.ProofHash,
        "zkVerify_tx", receipt.ZkVerifyTxHash,
        "base_tx", tx.Hash())

    return nil
}

The key to this design is not uploading proofs themselves to Base or Ethereum. By recording only verification results (hashes) from zkVerify:

  • Minimize Base L2 data costs
  • Block cost propagation to Ethereum L1
  • Verification integrity guaranteed by zkVerify consensus

Performance Measurement Results

Actual performance measured on testnet (1,000 transaction batch basis):

MetricDirect Ethereum VerificationzkVerify IntegrationImprovement
Verification Cost (gas)~280,000~25,00091%
Verification Latency15-30 sec<1 sec95%
Cost per Batch ($, 50 gwei)$42$3.891%

These results align with the 91% cost reduction target presented in the zkVerify whitepaper.

Sparse Merkle Tree: Mathematical Foundation of State Synchronization

Why SMT: Limitations of Patricia Trie

Ethereum uses a Modified Patricia Trie (MPT) for state management. However, MPT is inadequate for Oraclizer’s requirements:

Patricia Trie Problems:

  1. Non-deterministic Structure: Tree structure changes based on insertion order
  2. No Non-inclusion Proofs: Cannot prove a specific key does not exist
  3. Path Compression Complexity: Difficult to handle variable-length paths in zk circuit implementation

Oraclizer’s SMT Requirements:

  • Deterministic Structure: Same dataset → same root hash guarantee (essential for cross-chain verification)
  • Non-inclusion Proofs: Absence proofs like “this asset has been burned”
  • zk-friendly: Efficient verification possible in SNARK circuits

Sparse Merkle Tree satisfies all these requirements.

SMT Basic Structure

SMT is a complete binary tree with \(2^{256}\) leaves. Most leaves are empty (DEFAULT_VALUE), storing only leaves with actual data:

                     ROOT
                   /      \
                  /        \
            [H_left]    [H_right]
            /    \        /    \
          ...   ...    ...    ...
         /  \                  /  \
      [D0] [V1]             [D0] [V2]

D0: Default value (empty)
V1, V2: Actual data

Mathematical Definition:

For arbitrary key-value pair \((k, v)\):

  • Leaf position: \(\text{leaf\_index} = \text{hash}(k) \bmod 2^{256}\)
  • Leaf hash: \(H_{\text{leaf}} = \text{hash}(k \parallel v)\) if non-empty, else \(D_0\)
  • Parent hash: \(H_{\text{parent}} = \text{hash}(H_{\text{left}} \parallel H_{\text{right}})\)

In this structure, default subtree optimization is key:

If H_left == D_h and H_right == D_h, then
→ H_parent = D_{h+1} (pre-computed default hash)

Where D_h is the default hash at height h:
$$D_0 = hash(EMPTY)$$
$$D_{h+1} = hash(D_h || D_h)$$

Incremental Update Mechanism

State synchronization requires continuous updates. SMT’s incremental update efficiency:

Sparse Merkle Tree: Incremental Update Process 1. Initial State (Height = 3) ROOT H_L H_R D₂ V₁ D₂ V₂ 2. Path Identification & Update (K = V₁ → V₁’) ROOT’ H_L’ H_R D₂ V₁’ D₂ V₂ Sibling 3. Batch Update Optimization: Common Ancestor Grouping Group A Common Ancestor: Node_5 Updates: {K₁, K₂, K₃} Parallel Processing Group B Common Ancestor: Node_8 Updates: {K₄, K₅} Parallel Processing Merge New Root Complexity Analysis Single Update: O(log n) Naive Batch (m updates): O(m × log n) Optimized Batch: O(m + log n) ✓ 86% improvement for large batches
1
Initial State
ROOT
H_L
H_R
D₂
V₁
D₂
V₂
Height = 3
2
Path Identification
ROOT’
H_L’
H_R
D₂
V₁’
D₂
V₂
↑ Sibling collected for proof
O(log n) update
3
Batch Optimization
Group A
Updates: K₁, K₂, K₃
Group B
Updates: K₄, K₅
Parallel Processing → Merge
Naive: O(m × log n)
Optimized: O(m + log n)
✓ 86% improvement
Figure 2: Sparse Merkle Tree Incremental Update Mechanism with Batch Optimization
// SMT Update Interface
type SparseMerkleTree struct {
    root  []byte
    store KeyValueStore
    hasher hash.Hash
}

// Single Update: O(log N) complexity
func (t *SparseMerkleTree) Update(key, value []byte) (newRoot []byte, proof *Proof, err error) {
    // 1. Compute key path (256 bits)
    path := t.hasher.Sum(key) 

    // 2. Traverse path from root to leaf
    siblings := make([][]byte, 256)
    currentNode := t.root

    for depth := 0; depth < 256; depth++ {
        bit := getBit(path, depth)

        // Load current node's children
        left, right := t.getChildren(currentNode)

        // Store sibling (for proof)
        if bit == 0 {
            siblings[depth] = right
            currentNode = left
        } else {
            siblings[depth] = left
            currentNode = right
        }
    }

    // 3. Update leaf
    newLeaf := t.hasher.Sum(append(key, value...))

    // 4. Hash backward to root
    currentHash := newLeaf
    for depth := 255; depth >= 0; depth-- {
        bit := getBit(path, depth)

        if bit == 0 {
            currentHash = t.hasher.Sum(append(currentHash, siblings[depth]...))
        } else {
            currentHash = t.hasher.Sum(append(siblings[depth], currentHash...))
        }
    }

    // 5. Store new root
    t.root = currentHash

    // 6. Generate Merkle proof
    proof = &Proof{
        Key:      key,
        Value:    value,
        Siblings: siblings,
        Root:     currentHash,
    }

    return currentHash, proof, nil
}

Batch Update Optimization:

Research shows naive SMT batch updates have \(\mathcal{O}(m \log n)\) complexity (m: number of updates, n: tree size)[6]. We improved this through common ancestor optimization:

func (t *SparseMerkleTree) BatchUpdate(updates []KeyValue) (newRoot []byte, err error) {
    // 1. Group updates by common ancestor
    pathGroups := groupByCommonAncestor(updates)

    // 2. Process each group in parallel
    var wg sync.WaitGroup
    results := make(chan []byte, len(pathGroups))

    for _, group := range pathGroups {
        wg.Add(1)
        go func(g []KeyValue) {
            defer wg.Done()
            // Recompute only common subtree
            subtreeRoot := t.updateSubtree(g)
            results <- subtreeRoot
        }(group)
    }

    wg.Wait()
    close(results)

    // 3. Merge subtree roots
    newRoot = t.mergeSubtreeRoots(results)
    t.root = newRoot

    return newRoot, nil
}

Non-inclusion Proofs

One of SMT’s powerful features is non-inclusion proofs. This is crucial in RWA state synchronization:

Scenario: “This bond token has matured and been burned”

// Generate Non-inclusion Proof
func (t *SparseMerkleTree) ProveNonInclusion(key []byte) (*NonInclusionProof, error) {
    path := t.hasher.Sum(key)

    // Descend path until default node found
    siblings := make([][]byte, 0)
    currentNode := t.root

    for depth := 0; depth < 256; depth++ {
        bit := getBit(path, depth)
        left, right := t.getChildren(currentNode)

        if bit == 0 {
            siblings = append(siblings, right)
            if bytes.Equal(left, defaultHashes[255-depth]) {
                // Default subtree found → key absence proof
                return &NonInclusionProof{
                    Key:             key,
                    Siblings:        siblings,
                    DefaultDepth:    depth,
                    Root:            t.root,
                }, nil
            }
            currentNode = left
        } else {
            siblings = append(siblings, left)
            if bytes.Equal(right, defaultHashes[255-depth]) {
                return &NonInclusionProof{
                    Key:             key,
                    Siblings:        siblings,
                    DefaultDepth:    depth,
                    Root:            t.root,
                }, nil
            }
            currentNode = right
        }
    }

    // Reached leaf → different key exists
    return nil, fmt.Errorf("key exists in tree")
}

Verification Process:

The verifier confirms:

  1. Default hash found at specific depth of provided path
  2. Recompute to root using sibling hashes
  3. Computed root == provided root

$$\text{Verify}: H_{\text{computed}} \stackrel{?}{=} H_{\text{root}}$$


Validium/Volition: Flexibility Based on Regulatory Requirements

Data Availability Trilemma

In zk-Rollup design, data availability (DA) is a critical decision:

DA MethodSecurityCostRegulatory Transparency
On-chain (Rollup)HighestHighFull Disclosure
Off-chain (Validium)MediumLowLimited
Hybrid (Volition)SelectiveFlexibleSelective

Oraclizer adopted the Volition approach. This structure allows DA layer selection per transaction:

General RWA Transactions → Validium (Avail DA)
Requiring Regulatory Audit → Rollup (Base L2 on-chain)

Avail DA Integration

In Validium mode, we use Avail as the DA layer:

// Avail DA Submission Interface
type AvailDA struct {
    client  *avail.Client
    encoder *DataEncoder
}

func (a *AvailDA) SubmitBatch(batch *Batch) (*DACommitment, error) {
    // 1. Compress batch data
    compressed := a.encoder.Compress(batch.Transactions)

    // 2. Submit data to Avail
    availTx, err := a.client.SubmitData(compressed)
    if err != nil {
        return nil, fmt.Errorf("Avail submission failed: %w", err)
    }

    // 3. Wait for data availability proof from Avail
    daProof, err := a.client.WaitForInclusion(availTx.Hash)
    if err != nil {
        return nil, fmt.Errorf("DA proof timeout: %w", err)
    }

    // 4. Generate commitment (hash to record on L3)
    commitment := &DACommitment{
        DataHash:     hash(compressed),
        AvailBlock:   daProof.BlockNumber,
        AvailTxIndex: daProof.TxIndex,
        Timestamp:    time.Now(),
    }

    return commitment, nil
}

Volition Switching Logic:

func (s *Sequencer) ProcessTransaction(tx *Transaction) error {
    // Check regulatory flag
    if tx.RequiresRegulatoryAudit {
        // Rollup mode: Record full data on Base L2
        return s.submitToBaseL2(tx)
    }

    // Check asset type policy
    if s.policyEngine.RequiresOnChainDA(tx.AssetType) {
        return s.submitToBaseL2(tx)
    }

    // Default: Validium (Avail)
    return s.submitToAvail(tx)
}
Volition Data Flow: From Decision to Convergence Transaction Request Asset Transfer + Metadata DA Mode Selection 1. Regulatory Audit Check 2. Asset Type Policy Check 90% Validium 10% Rollup Validium Path 1. Batch Preparation: Collect multiple TXs in batch 2. Avail Submission: Send to Avail → Get DA proof 3. Commitment Hash: Store hash(data) + Avail reference Cost: ~$0.05 per TX Rollup Path 1. Full Data Prep: Include all TX data + proofs 2. Base L2 Storage: Store complete data on-chain 3. Audit Trail: Full transparency for regulators Cost: ~$0.50 per TX Unified State Processing Both paths converge here: • Generate unified state root (SMT) • Create zk-SNARK proof for state transition • Single proof regardless of DA mode zkVerify → Base L2 Settlement • Unified proof verification • Single state root commitment • DA mode transparent to end users Key Benefits ✓ Cost optimization (90% low-cost) ✓ Regulatory compliance when needed ✓ Unified state regardless of path ✓ Single proof for all modes
Transaction Input & Decision
Transaction Request
Asset Transfer + Metadata
DA Mode Selection
1. Regulatory Audit Check
2. Asset Type Policy Check
Parallel Processing Paths
Validium (90%)
1. Batch TXs
2. Submit to Avail
3. Store hash
Cost: ~$0.05
Rollup (10%)
1. Full data prep
2. Base L2 store
3. Audit trail
Cost: ~$0.50
↓ Converge ↓
Unified State Processing
Both Paths Merge Here
• Generate unified SMT state root
• Create single zk-SNARK proof
• Same proof for both DA modes
zkVerify → Base L2
• Unified proof verification
• Single state commitment
• DA mode transparent to users
Key Benefits
✓ 90% transactions at low cost
✓ 10% regulatory compliance
✓ Single unified state
✓ One proof for all paths
Figure 3: Volition Data Flow – From Parallel Paths to Unified State

This design provides balance between cost and transparency:

  • General transactions: Low-cost operation via Avail
  • Regulatory audits: Full transparency via Base L2 on-chain

Regulatory Compliance Layer: ERC-TRUST Integration

Protocol-Level Regulatory Control

Oraclizer L3’s differentiation is that regulatory compliance is mandatory, not optional. This is implemented at the protocol level, not the application layer.

┌─────────────────────────────────────┐
│   Application Layer (RWA Tokens)    │
├─────────────────────────────────────┤
│   Regulatory Compliance Layer       │ ← L3 Core
│   - RAI (Regulated Asset Identity)  │
│   - 6 Enforcement Actions           │
│   - Regulatory Authority Hierarchy  │
├─────────────────────────────────────┤
│   State Management (SMT)            │
├─────────────────────────────────────┤
│   Consensus (D-quencer)             │
└─────────────────────────────────────┘

RAI (Regulated Asset Identity) System

ERC-TRUST standard’s RAI, implemented in Oraclizer as Oracle Contract ID (OCID), is natively integrated at the L3 level:

// L3 Native RAI Structure
struct RegulatedAssetIdentity {
    bytes32 ocid;              // Oracle Contract ID
    address onChainAddress;    // L3 address
    bytes32 zkIdCommitment;    // zk proof-based identity commitment
    uint8 kycLevel;            // KYC verification level (1-5)
    uint256 lastVerification;  // Last verification time
    bytes32[] regulatoryFlags; // Regulatory flags array
}

// RAI Validation Logic (Integrated in L3 Executor)
function validateTransaction(
    Transaction calldata tx,
    bytes calldata zkProof
) internal returns (bool) {
    // 1. Verify identity with zk proof (without exposing off-chain info)
    if (!verifyIdentityProof(tx.from, zkProof)) {
        revert InvalidIdentityProof();
    }

    // 2. Query RAI records
    RegulatedAssetIdentity storage fromRAI = raiRegistry[tx.from];
    RegulatedAssetIdentity storage toRAI = raiRegistry[tx.to];

    // 3. Verify regulatory requirements
    if (fromRAI.kycLevel < requiredKycLevel[tx.assetType]) {
        revert InsufficientKYC();
    }

    // 4. Check blacklist/regulatory flags
    if (hasRegulatoryRestriction(fromRAI) || hasRegulatoryRestriction(toRAI)) {
        revert RegulatoryRestriction();
    }

    return true;
}

System-wide AML Implementation:

RAI’s innovation is cross-chain identity tracking. RAI implemented at L3 level guarantees:

OCID: oracle://chain-137/address-0xABC.../contract-0x123...

This OCID:
- Generated on L3
- Maintained when bridged to Base L2
- Remains identical when crossing to Arbitrum, Optimism, etc.
- Same regulatory status applied across all chains

Six Regulatory Actions

L3 Regulatory Compliance Layer: Protocol-Level Enforcement Application Layer RWA Tokens, DeFi Protocols Regulatory Compliance Layer (L3 Core Protocol) RAI System Identity + KYC 6 Enforcement Actions Atomic Execution Authority Hierarchy Global → National → Local State Management (SMT) Sparse Merkle Tree Storage Consensus (D-quencer) Priority Regulatory Actions 6 Regulatory Enforcement Actions FREEZE Temporary asset suspension • Reversible action • Investigation period SEIZE Court-ordered custody • Ownership retained • Control transferred CONFISCATE Permanent forfeiture • Ownership transferred • Irreversible action $ LIQUIDATE Forced asset sale • Market price execution • Debt settlement RESTRICT Conditional limitations • Partial control • Specific conditions RECOVER Asset restoration • Return to owner • Fraud recovery RAI (Regulated Asset Identity) System Architecture Oracle Contract ID oracle://chain-137/ address-0xABC…/ contract-0x123… Cross-chain persistent zk Identity Commitment • Private info off-chain • ZK proof on-chain • Selective disclosure Privacy preserved KYC Verification Levels Level 1: Basic Level 2: Enhanced Level 3: Institutional Asset-specific requirements System-wide AML • Cross-chain tracking • Pattern detection • Real-time monitoring Protocol-level enforcement
Regulatory Compliance Layer
L3 Core Protocol Implementation
FREEZE
Temporary suspension, reversible
SEIZE
Court custody, ownership retained
CONFISCATE
Permanent forfeiture
$
LIQUIDATE
Forced sale for debt
RESTRICT
Conditional limitations
RECOVER
Restore to owner
RAI System Components
OCID: Cross-chain persistent identity
zk Commitment: Privacy-preserved verification
KYC Levels: 1-3 verification tiers
System AML: Protocol-level monitoring
Authority Hierarchy
Global → National → Local
Priority-based execution
Figure 4: L3 Regulatory Compliance Layer with 6 Enforcement Actions and RAI System

The six regulatory actions defined in ERC-TRUST are natively integrated into the L3 Executor:

// L3 Regulatory Action Handler
type RegulatoryActionHandler struct {
    stateDB     *StateDB
    raiRegistry *RAIRegistry
    eventLog    *EventLogger
}

// FREEZE: Temporary asset freeze
func (h *RegulatoryActionHandler) Freeze(
    assetID common.Hash,
    authority RegulatoryAuthority,
    reason string,
) error {
    asset := h.stateDB.GetAsset(assetID)
    if asset == nil {
        return ErrAssetNotFound
    }

    // Verify authority
    if !h.hasFreezingAuthority(authority, asset) {
        return ErrUnauthorized
    }

    // State change
    asset.Status = StatusFrozen
    asset.FrozenBy = authority.ID
    asset.FrozenReason = reason
    asset.FrozenAt = time.Now()

    // Update SMT
    h.stateDB.UpdateAsset(asset)

    // Emit event
    h.eventLog.Emit(RegulatoryActionEvent{
        Type:      ActionFreeze,
        AssetID:   assetID,
        Authority: authority,
        Timestamp: time.Now(),
    })

    return nil
}

// CONFISCATE: Permanent confiscation
func (h *RegulatoryActionHandler) Confiscate(
    assetID common.Hash,
    authority RegulatoryAuthority,
    courtOrder *CourtOrder,
) error {
    // Verify court order
    if !h.verifyCourtOrder(courtOrder) {
        return ErrInvalidCourtOrder
    }

    asset := h.stateDB.GetAsset(assetID)

    // Transfer ownership
    originalOwner := asset.Owner
    asset.Owner = authority.TreasuryAddress
    asset.Status = StatusConfiscated
    asset.ConfiscationOrder = courtOrder.Hash()

    // Update RAI (maintain original owner record)
    rai := h.raiRegistry.Get(originalOwner)
    rai.AddRegulatoryFlag(FlagConfiscated, assetID)

    h.stateDB.UpdateAsset(asset)
    h.raiRegistry.Update(rai)

    return nil
}

These actions execute atomically at the L3 Executor level. Unlike general transactions, regulatory actions:

  • Priority Processing: D-quencer processes before normal txs
  • Non-reversible: Cannot be reversed by conventional means once executed
  • Audit Trail: All actions recorded in immutable logs

D-quencer and L3 Integration

Regulatory Action Priority Management

D-quencer (decentralized sequencer) ensures immediate execution of regulatory actions on L3:

type PriorityQueue struct {
    regulatoryActions []*RegulatoryTx
    normalTxs         []*Transaction
    mu                sync.Mutex
}

func (d *Dquencer) SelectTransactions(blockGasLimit uint64) []*Transaction {
    d.mu.Lock()
    defer d.mu.Unlock()

    selected := make([]*Transaction, 0)
    gasUsed := uint64(0)

    // 1. Priority process regulatory actions (ignore gas limit)
    for _, regTx := range d.regulatoryActions {
        selected = append(selected, regTx)
        gasUsed += regTx.EstimateGas()
    }
    d.regulatoryActions = nil // Process all

    // 2. Process normal transactions with remaining gas
    for _, tx := range d.normalTxs {
        if gasUsed+tx.EstimateGas() > blockGasLimit {
            break
        }
        selected = append(selected, tx)
        gasUsed += tx.EstimateGas()
    }

    return selected
}

Separation of Consensus and Verification

L3 architecture clearly separates consensus (D-quencer) and verification (zkProver):

┌─────────────────────────────────────┐
│    D-quencer (Consensus Layer)      │
│    - Transaction ordering           │
│    - Regulatory action priority     │
│    - Block proposal                 │
└────────────┬────────────────────────┘
             │ Proposed block
             ↓
┌─────────────────────────────────────┐
│    zkProver (Execution & Proof Gen) │
│    - Execute state transitions      │
│    - Generate zk proofs             │
│    - Update SMT root                │
└────────────┬────────────────────────┘
             │ Proof + new state root
             ↓
┌─────────────────────────────────────┐
│    zkVerify (Verification Layer)    │
│    - Verify proofs                  │
│    - Issue verification certificates│
└────────────┬────────────────────────┘
             │ Verification complete
             ↓
┌─────────────────────────────────────┐
│    Base L2 (Settlement)             │
│    - Record verification reference  │
│    - Final finality                 │
└─────────────────────────────────────┘

This structure provides Stage 1 rollup security while maintaining efficiency.


L3 to L1: Complete Cryptographic Finality

Layer-by-Layer Security Guarantees

Oraclizer L3’s finality undergoes four-stage verification:

Stage 1: L3 Consensus (D-quencer)

  • BLS signature-based consensus
  • Minimum 67% node signatures required
  • Instant finality (1-2 seconds)

Stage 2: zk Proof Generation (zkProver)

  • Proof of state transition correctness
  • SNARK circuit execution (~30 seconds)

Stage 3: Verification (zkVerify)

  • Proof verification completion
  • Verification certificate issuance (<1 second)

Stage 4: Final Settlement (Base → Ethereum)

  • Record verification reference on Base L2
  • Optimistic Rollup finality to Ethereum L1
  • Final confirmation (~7 days, challenge period)

Mathematical Security Analysis

L3 system security holds under the following assumptions:

Assumption 1 (D-quencer Honesty): \(\geq 67\%\) nodes act honestly

Assumption 2 (zk Proof Soundness): Soundness of SNARK proof system

$$\Pr[\text{Verifier accepts false proof}] \leq 2^{-128}$$

Assumption 3 (Base L2 Security): Base’s Optimistic Rollup security

  • At least 1 honest verifier exists
  • Fraud proof submission possible within challenge period

Theorem: If the above 3 assumptions hold, validity of L3 state transitions is probabilistically guaranteed.

$$\Pr[\text{Invalid state finalized}] \leq \Pr[\text{D-quencer attack}] + \Pr[\text{SNARK break}]$$

In practice:

  • D-quencer attack probability < \(10^{-9}\) (requires 67%+ collusion)
  • SNARK break probability < \(2^{-128}\) (cryptographic assumption)
  • Total attack success probability < \(10^{-9}\) (negligible)

Versus Zcash: Differences in Technical Philosophy

Privacy vs Auditability

Zcash’s Approach:

Entire Transaction → zk-SNARK Proof → Complete Concealment
  • Advantage: Complete privacy
  • Disadvantage: Non-regulatable, AML impossible

Oraclizer’s Approach:

Transaction → RAI Verification → Selective Disclosure zk Proof → Auditable Privacy
  • Advantage: Privacy + regulatory compliance
  • Method: Selective disclosure decryptable only by regulatory authorities

Structural Differences

AspectZcashOraclizer
PurposeAnonymous paymentsRWA state synchronization
PrivacyComplete concealmentSelective disclosure
Regulatory ComplianceImpossibleProtocol level
Identity ManagementNoneRAI system
EnforcementImpossible6 actions
Cross-chainLimitedNative support

Use Case Differences

Zcash:

  • Anonymous peer-to-peer transfers
  • Regulatory evasion possibility → financial institution adoption impossible

Oraclizer:

  • Institutional RWA transactions
  • Regulatory compliance → traditional finance integration possible

This difference is not a simple technical choice, but a fundamental question about blockchain’s future vision:

Complete anonymity vs auditable privacy—which truly enables mass adoption?

We chose the latter.


Major Development Challenges and Solutions

1. CDK Customization Complexity

Problem: Polygon CDK is a general-purpose zk-Rollup framework, not optimized for state synchronization

Solution:

  • Integrate RAI validation logic into Executor
  • Completely replace Sequencer with D-quencer
  • Re-implement State DB based on SMT

Code Example (State DB Modification):

// Existing CDK State DB (MPT-based)
type StateDB struct {
    trie *trie.Trie
    // ...
}

// Oraclizer State DB (SMT-based)
type OraclizerStateDB struct {
    smt          *SparseMerkleTree
    raiRegistry  *RAIRegistry
    assetDB      *AssetDatabase
    eventLog     *EventLogger
}

func (db *OraclizerStateDB) UpdateAsset(asset *RWAAsset) error {
    // 1. RAI verification
    if !db.raiRegistry.IsValid(asset.Owner) {
        return ErrInvalidRAI
    }

    // 2. SMT update
    key := asset.ID.Bytes()
    value := asset.Encode()
    newRoot, proof, err := db.smt.Update(key, value)
    if err != nil {
        return err
    }

    // 3. Event logging
    db.eventLog.Record(AssetUpdateEvent{
        AssetID:     asset.ID,
        NewRoot:     newRoot,
        Proof:       proof,
        Timestamp:   time.Now(),
    })

    return nil
}

2. Initial zkVerify Integration Issues

Problem: Need to convert fflonk proofs generated by zkProver to zkVerify format

Solution:

  • Standardize proof serialization
  • Close collaboration with zkVerify SDK
// Proof Conversion Layer
func SerializeProofForZkVerify(cdkProof *zkProver.Proof) (*zkverify.ProofSubmission, error) {
    // CDK zkProver generates fflonk proofs by default
    // fflonk: 768 bytes (24 big-endian 256-bit integers)
    
    submission := &zkverify.ProofSubmission{
        ProofSystem:  zkverify.fflonk,
        Proof:        cdkProof.SerializedProof,
        PublicInputs: cdkProof.PublicInputs,
        VK:           cdkProof.VerifyingKey,
    } 
    return submission, nil
}

3. SMT Performance Optimization

Problem: Naive SMT implementation is slow with large-scale state

Solution:

  • Node batching (16 leaves per node)
  • Disk I/O optimization (using RocksDB)
  • Parallel proof generation

Performance Measurements:

State SizeNaive SMTOptimized SMTImprovement
10K assets250 ms35 ms86%
100K assets2.8 sec420 ms85%
1M assets31 sec4.8 sec84%

Future Research Directions

1. Incremental Proofs

Currently, we generate independent proofs for each block. Incremental proofs reuse previous proofs to improve efficiency:

$$\pi_n = f(\pi_{n-1}, \Delta_n)$$

Where \(\pi_n\) is the proof for block n, \(\Delta_n\) is the state change.

2. Verkle Tree Integration Possibility

Research on SMT → Verkle migration in preparation for Ethereum’s Verkle Tree transition:

  • Advantage: Dramatic proof size reduction (10KB → 150B)
  • Disadvantage: Complex cryptography (KZG commitment)

3. Cross-L3 Bridging

Direct bridging between multiple L3s (without going through L2/L1):

L3_A ←→ Shared zkVerify ←→ L3_B

Conclusion: A New Balance Point Between Privacy and Regulation

Oraclizer’s L3 zk-Rollup seeks harmony between technical innovation and regulatory reality. The vision of “complete concealment” demonstrated by Zcash is appealing, but it cannot coexist with the financial system.

We chose a different path: auditable privacy. This provides:

  • General Users: Privacy protection (RAI + zk proofs)
  • Regulatory Authorities: Selective access (under court order)
  • Financial Institutions: Regulatory compliance guarantee (6 enforcement actions)

This balance point is not simply “a bit of both.” It’s structurally designed coexistence:

  • Protocol-Level Regulation: Mandatory, not optional
  • zk Proof Privacy: Provided by default
  • Selective Transparency: Disclosed only when necessary

Over the past six months of development, we’ve proven this vision is not merely theoretical but tangible reality:

  • Polygon CDK customization: Design finalized and prototype implementation completed
  • SMT-based state management: Alpha implementation with optimization
  • RAI system: Prototype completed with core functionality

The next step is security audits and performance tuning toward testnet launch. We’re targeting early 2026 testnet deployment, which will become a new standard for regulatory-compliant RWA tokenization.

Zcash showed one extreme of privacy. We’re pioneering not the opposite extreme, but a sustainable middle ground. And this middle ground will enable the blockchain entry of trillions of dollars in traditional assets.


References

[1]. Delphi Digital. (2025). zkVerify: Optimizing ZK Proof Verification At Scale. https://members.delphidigital.io/reports/zkverify-optimizing-zk-proof-verification-at-scale

[2]. Kelvin Fichter. (2018). What’s a Sparse Merkle Tree? https://medium.com/@kelvinfichter/whats-a-sparse-merkle-tree-acda70aeb837

[3]. Linea Documentation. (2025). EVM State Manager. https://docs.linea.build/technology/state-manager

[4]. arXiv. (2023). One-Phase Batch Update on Sparse Merkle Trees for Rollups. https://arxiv.org/abs/2310.13328

[5]. Polygon Documentation. (2025). zkProver Architecture. https://docs.polygon.technology/zkEVM/architecture/zkprover/

Read Next

Functor Laws: When Math Wasn’t the Wall
A research-journal account of mechanizing the functor laws and the degree-hierarchy natural transformation in Isabelle/HOL, where the obstacles were almost never the mathematics. The measure decrease I feared closed at once; a reserved keyword broke seven builds; a finiteness clash forced a redefinition; and the code overturned my belief that glue gives validity.
Oraclizer Core ⋅ Jun 06, 2026
Insurance and Recovery Economics: Preparing for Black Swan Events
Earlier designs cut node risk by 73%, but the unpredictable 27% needs different rules. This study fixes how a staking insurance pool is sized (15% of stake, not protected value), bootstrapped, and banded; why a reserve held in its own token collapses with it; and how session protection follows the sync-degree hierarchy when security breaks mid-session.
Oraclizer Core ⋅ May 29, 2026
Tokenized Securities Under the CLARITY Act: The Weight of Codification
The CLARITY Act tokenized securities clause settles a single proposition in statute: tokenization is a delivery method, not a new asset class. That one sentence codifies the regulatory status of tokenized securities in U.S. law for the first time and derives an entire infrastructure specification for boundaries the token crosses.
Oraclizer Core ⋅ May 23, 2026
Sync Degree Hierarchy: Classifying What Assets Demand from State Synchronization
Sync degree hierarchy turns sync requirement strength into a four-level classification axis for RWA assets. S₀ static through S₃ atomic state binding form a reduction relation where causal consistency separates S₁ from S₂. Existing oracles, structurally two independent channels, are capped at S₁ by definition. Regulatory action forces S₃.
Oraclizer Core ⋅ May 20, 2026