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
The DERO hard cap of 21 million is defined in the protocol emission schedule. The remaining supply will be mined over many years through block rewards.
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
Protocol-Level Documentation
For deeper understanding of the cryptographic foundations:
- Payload vs Transaction Proofs (opens in a new tab) - Understanding the distinction between proof types at the protocol level
- Balance Mechanics (opens in a new tab) - How DERO's homomorphic balance system works