Skip to main content

Overview

The UnifiedPaymentVerifier contract verifies payment proofs for multiple payment methods (Venmo, PayPal, Wise, etc.) using a unified, configurable architecture. This contract replaces individual payment verifiers with a single contract that can be easily swapped without affecting critical state. Key Features:
  • Supports multiple payment methods with custom configuration
  • Uses EIP-712 signature validation for payment attestations
  • Validates offchain payment attestations through the AttestationVerifier
  • Prevents double-spending via nullifier registry
  • Ensures trust anchor integrity for off-chain verification
Contract Location: contracts/unifiedVerifier/UnifiedPaymentVerifier.sol

Architecture

The UnifiedPaymentVerifier inherits from BaseUnifiedPaymentVerifier and implements the IPaymentVerifier interface. It coordinates with several other contracts:
  • AttestationVerifier: Validates witness signatures on payment attestations
  • NullifierRegistry: Prevents payment reuse (double-spending)
  • OrchestratorRegistry: Authorizes orchestrators to call verification
  • Orchestrator: Provides intent data for validation

Payment Attestation Structure

Payment attestations are EIP-712 signed messages containing:
The data field contains:

EIP-712 Signature Validation

The contract uses EIP-712 typed structured data hashing and signing. The domain separator is computed at deployment:
The PaymentAttestation type hash is:

Verification Process

The _verifyAttestation function:
  1. Constructs the struct hash from attestation fields
  2. Creates the EIP-712 digest: keccak256("\x19\x01" || DOMAIN_SEPARATOR || structHash)
  3. Verifies data integrity by checking keccak256(attestation.data) == attestation.dataHash
  4. Calls the AttestationVerifier to validate witness signatures
Source: contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:183-214

Payment Verification Flow

The verifyPayment function executes the following steps:

1. Decode Attestation

2. Decode Payment Details and Intent Snapshot

3. Validate Payment Method

4. Validate Intent Snapshot

Reads the intent from the Orchestrator and validates all fields match:
  • Intent hash
  • Payee details
  • Amount
  • Payment method
  • Fiat currency
  • Conversion rate
  • Signal timestamp
  • Timestamp buffer (must be ≤ 48 hours)
Source: contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:220-234

5. Verify Attestation Signatures

6. Nullify Payment

Prevents double-spending by creating a unique nullifier:
The nullifier combines payment method and payment ID to prevent collisions across different payment systems. Source: contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:242-245

7. Calculate Release Amount

Caps the release amount to the intent amount:

8. Emit Payment Details

Emits the PaymentVerified event for off-chain reconciliation:
Source: contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:53-61

Access Control

The verifyPayment function can only be called by authorized orchestrators:
This prevents griefing attacks since the verifier has write permissions on the nullifier registry.

Configuration Management

Inherited from BaseUnifiedPaymentVerifier:

Adding Payment Methods

Adds a new supported payment method. The payment method should be the keccak256 hash of the lowercase method name (e.g., keccak256("venmo")).

Removing Payment Methods

Updating Attestation Verifier

Allows swapping the attestation verifier implementation. Source: contracts/unifiedVerifier/BaseUnifiedPaymentVerifier.sol:74-111

Security Considerations

Double-Spend Prevention

The nullifier combines both payment method and payment ID to create a unique identifier:
This prevents collisions where the same payment ID could exist across different payment methods.

Data Integrity

The contract verifies that the data hash in the attestation matches the actual data:
This ensures witnesses signed the exact payment details being verified.

Intent Validation

All intent fields are validated against the on-chain intent state to prevent attestation reuse or manipulation:
  • Prevents attestations from being used for different intents
  • Ensures payment details match what was agreed upon
  • Validates timestamp buffer is within acceptable range (≤ 48 hours)

Release Amount Capping

The release amount is always capped to the intent amount:
This prevents over-release of tokens even if the attestation specifies a higher amount.

Example Usage

Events

PaymentVerified

Emitted when a payment is successfully verified. Used for off-chain reconciliation and monitoring.

PaymentMethodAdded

PaymentMethodRemoved

AttestationVerifierUpdated