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:
-
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.
-
Integer Overflow Protection: Amounts near 2^63 can cause integer wraparound bugs. These are blocked.
-
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 Type | Result |
|---|---|
| 184 trillion DERO proofs | REJECTED |
| Any amount > 22M DERO | REJECTED |
| int64 wraparound attacks (>= 2^63) | REJECTED |
| Amounts > current supply (~16.5M) | WARNING |
| Large amounts (> 1M DERO) | INFO |
| Suspiciously round numbers | WARNING |
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:
- Buffer for edge cases: Rounding errors or minor timing issues
- Future-proof: If supply approaches 21M, legitimate proofs still work
- 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
- Block Explorer - Full explorer features
- Security Features - Hologram's security model