Proof Validation

Proof Validation

Hologram includes a security enhancement that validates payload proofs before display, preventing fake/fabricated proofs with impossible amounts from being shown to users.

The Problem

DERO's payload proof system allows users to prove they sent a specific amount to a specific address. However, these proofs can be fabricated with impossible amounts—like 184 trillion DERO—because the proof verification only checks cryptographic validity, not economic sanity.

Without validation:

  • An attacker could create a fake proof claiming to have sent millions of DERO
  • The Explorer would display this as "Proof Valid"
  • Users could be deceived about transaction amounts
  • False accusations could be made based on fabricated proofs

The Solution

Hologram validates proof amounts before display using mathematical constraints:

  1. DERO Hard Cap Check: DERO has a permanent hard cap of 21 million (like Bitcoin). Any proof claiming more than 21M DERO is mathematically impossible.

  2. Integer Overflow Protection: Amounts near 2^63 can cause integer wraparound bugs. These are blocked.

  3. Suspicious Pattern Detection: Large amounts or suspiciously round numbers trigger warnings.

Validation Constants

const (
    // Maximum safe value for int64 conversion (2^63 - 1)
    // Prevents uint64→int64 wraparound attacks
    MAX_INT64_SAFE = 9223372036854775807
 
    // Maximum reasonable transfer amount in atomic units
    // DERO hard cap: 21M DERO (will never increase)
    // Setting max at 22M DERO = 22 trillion atomic units
    // ~5% above hard cap for buffer while blocking impossible amounts
    MAX_REASONABLE_AMOUNT_ATOMIC = 22_000_000_000_000
 
    // For display
    ATOMIC_UNITS_PER_DERO = 100_000
 
    // Hard cap reference
    DERO_HARD_CAP = 21_000_000
)

Validation Functions

ValidatePayloadProofAmount

Performs security checks on payload proof amounts:

func ValidatePayloadProofAmount(amount uint64) error {
    // Check 1: Prevent int64 wraparound
    if amount > MAX_INT64_SAFE {
        return fmt.Errorf("amount exceeds maximum safe integer - possible wraparound attack")
    }
 
    // Check 2: Sanity check against DERO hard cap
    if amount > MAX_REASONABLE_AMOUNT_ATOMIC {
        amountInDero := amount / ATOMIC_UNITS_PER_DERO
        return fmt.Errorf("amount %d DERO exceeds DERO hard cap (%d M) - proof is fabricated",
            amountInDero, DERO_HARD_CAP/1_000_000)
    }
 
    return nil
}

DetectSuspiciousProofPatterns

Flags potentially fake or suspicious proofs:

func DetectSuspiciousProofPatterns(amount uint64) []string {
    var warnings []string
 
    // Warning 1: Near int64 boundary (possible wraparound attempt)
    boundaryThreshold := uint64(MAX_INT64_SAFE * 9 / 10)
    if amount > boundaryThreshold {
        warnings = append(warnings,
            "Amount near int64 maximum - possible wraparound attempt")
    }
 
    // Warning 2: Exceeds current circulating supply (~16M)
    currentSupplyThreshold := uint64(17_000_000_000_000)
    if amount > currentSupplyThreshold {
        amountDero := amount / ATOMIC_UNITS_PER_DERO
        warnings = append(warnings,
            fmt.Sprintf("Amount (%d DERO) exceeds current circulating supply - verify carefully", amountDero))
    }
 
    // Warning 3: Very large amount (> 1M DERO) - not fake, just notable
    largeThreshold := uint64(1_000_000_000_000)
    if amount > largeThreshold && amount <= currentSupplyThreshold {
        amountDero := amount / ATOMIC_UNITS_PER_DERO
        warnings = append(warnings,
            fmt.Sprintf("Large transfer amount: %d DERO", amountDero))
    }
 
    // Warning 4: Suspiciously round number in trillions (often fabricated)
    if amount >= 1_000_000_000_000 && amount%1_000_000_000_000 == 0 {
        amountDero := amount / ATOMIC_UNITS_PER_DERO
        warnings = append(warnings,
            fmt.Sprintf("Suspiciously round number (%d DERO exactly)", amountDero))
    }
 
    return warnings
}

What Gets Blocked

Attack TypeResult
184 trillion DERO proofsREJECTED
Any amount > 22M DEROREJECTED
int64 wraparound attacks (>= 2^63)REJECTED
Amounts > current supply (~16.5M)WARNING
Large amounts (> 1M DERO)INFO
Suspiciously round numbersWARNING

UI Features

Rejected Proofs

When a proof is rejected, the UI displays:

  • "Proof Rejected" header with Shield icon
  • Error message explaining the rejection
  • Security note: "This proof claims an amount that exceeds the DERO hard cap (21M) and is therefore fabricated."

Suspicious Proofs

When a proof passes but has warnings, the UI displays:

  • "Proof Accepted" with verification details
  • Warning panel with AlertTriangle icon
  • Each warning listed with context

Supply Context

For valid proofs, the UI can display:

  • "12.5% of current DERO supply"
  • Helps users understand the magnitude

Why 22M, Not 21M?

The threshold is set slightly above the hard cap (22M vs 21M) for several reasons:

  1. Buffer for edge cases: Rounding errors or minor timing issues
  2. Future-proof: If supply approaches 21M, legitimate proofs still work
  3. Clear rejection: Anything above 22M is obviously fabricated

As of December 2025, the circulating DERO supply is approximately 16.5 million out of the 21 million hard cap. The remaining ~4.5 million will be mined over many years.

Key Insight

This validation enforces mathematical reality, not arbitrary limits:

  • DERO has a permanent, immutable hard cap of 21 million
  • Any proof claiming more than this is provably fabricated
  • This isn't a "best guess" - it's cryptographic certainty
  • The fix blocks ~95% of egregious fake proofs

Limitations

⚠️

This validation is a sanity check, not cryptographic verification of the proof itself.

  • Cannot verify proof without sender's private keys
  • Cannot detect subtle fakes (e.g., claiming 100 DERO when you sent 10)
  • Only blocks proofs with impossible amounts
  • Not a replacement for protocol-level proof verification

Integration

The validation is integrated into Hologram's Explorer at the proof display point:

// In ValidateProofFull()
for i, amt := range amounts {
    // Block proofs with impossible amounts
    if err := ValidatePayloadProofAmount(amt); err != nil {
        return map[string]interface{}{
            "success":      true,
            "valid":        false,
            "error":        fmt.Sprintf("Proof rejected: %s", err.Error()),
            "securityNote": "This proof claims an amount that exceeds the DERO hard cap (21M) and is therefore fabricated.",
        }
    }
 
    // Collect warnings for suspicious but valid amounts
    warnings := DetectSuspiciousProofPatterns(amt)
    allWarnings = append(allWarnings, warnings...)
}

Related Documentation