Audit Reports

Audit Reports

UltraDAG has undergone extensive multi-pass auditing, resulting in 188+ bugs found and fixed. This page summarizes audit methodology, findings, and current security posture.


Audit Summary

MetricValue
Total bugs found and fixed188+
Critical bugs fixed15+
High severity bugs fixed20+
Audit passes completed12+
Tests passing836+ (core) + 64 (sim)
Jepsen fault injection tests14
Unsafe Rust instances0
Cargo audit vulnerabilities0
Cargo audit warnings0

Audit Methodology

Internal Multi-Pass Auditing

The codebase was audited through 12+ systematic passes, each targeting a specific concern:

PassFocus AreaKey Findings
Consensus correctnessDAG-BFT finality, vertex ordering, equivocationNon-deterministic slashing, ordering by topo_level
Supply invariantBalance tracking, minting, burningMultiple arithmetic overflow paths, fee clawback failures
P2P hardeningMessage handlers, rate limiting, syncUnbounded responses, deadlock in lock ordering
RPC validationInput validation, authentication, rate limitsZero-amount transfers, missing fee checks
Persistence safetyfsync, redb, checkpoint chainNo fsync before rename, state root serde-dependency
Cryptographic auditSignatures, hashing, domain separationHash collisions in variable-length fields
Staking economicsReward distribution, delegation, slashingUndelegating amounts inflating reward denominator
GovernanceProposal lifecycle, parameter changes, councilNon-deterministic proposal execution order
Transport encryptionNoise protocol, identity bindingHandshake parse().unwrap() panics
Cross-batch analysisEquivocation across finality batchesDouble/triple slash for single equivocation
Eclipse attackCheckpoint trust model, fresh nodesFresh node accepts fabricated checkpoint chain
Dependency auditThird-party crate security1 unmaintained dependency (fixed)

External Vulnerability Report

An external security report with 20 claimed vulnerabilities was triaged:

ResultCount
Valid (all previously known)3
False positives or already mitigated17

The 3 valid findings were:

  1. CheckpointSync trust on fresh nodes (VULN-01) — mitigated via checkpoint chain verification
  2. Dynamic validator inflation (VULN-02) — mitigated via --validators N flag
  3. Private keys in RPC (VULN-03) — mitigated via testnet gating

Notable Bug Categories

Consensus Determinism

Non-deterministic behavior across nodes is a consensus split vector. Findings and fixes:

BugDescriptionFix
Reward distribution orderHashMap iteration in distribute_round_rewards()Sort by address before iteration
Governance execution orderHashMap iteration in tick_governance()Sort proposals by ID
Vertex orderingtopo_level in sort key (locally computed)Order by (round, hash) only
Council emission orderHashMap iteration for council creditsSort council members by address
Pre-staking reward orderHashSet iteration of producersSort by address
Parent selection tiebreakUnstable sort on score collisionAdd hash-based tiebreaker

Supply Integrity

Bugs that could have caused supply inflation or deflation:

BugDescriptionFix
Fee clawback failureGovernance tx fee clawback logged but ignoredReturn SupplyInvariantBroken
Undelegating in denominatorReward denominator included undelegating amountsUse sum(effective_stake_of(v))
Observer reward hardcodedGovernance parameter for observer rate ignoredRead from governance_params
Unchecked .sum()11 instances of overflow-unsafe summationsaturating_add folds
Credit overflowcredit() used unchecked +=saturating_add()
Coinbase height trustedEngine trusted proposer-supplied height for rewardCompute from last_finalized_round

P2P Hardening

Network-layer vulnerabilities:

BugDescriptionFix
Eclipse attackFresh node CheckpointSync skipped chain verificationAlways verify chain to genesis hash
Chunk amplification4MB message with 1-byte chunks = 4M decrypt opsCap max chunks
Orphan buffer unbounded per peerSingle peer fills entire bufferPer-peer cap of 100
DagVertices unboundedNo cap on incoming vertex count.take(500)
RoundHashes amplificationUnbounded hash count generates GetParents floodCap at 1000 rounds, 100 hashes
Deadlock (3 instances)Inconsistent lock ordering between handlersUniform finality-before-state ordering

Persistence Safety

Data durability bugs:

BugDescriptionFix
No fsync before rename5 persistence paths used write + rename without fsyncwrite_and_fsync() + fsync_directory()
State root serde-dependentpostcard::to_allocvec() not version-stableHand-rolled canonical bytes
Broken checkpoint chainMissing predecessor produces [0u8; 32] chain linkSkip production, log error
configured_validator_count not persistedLost on restart, changed reward splittingSave in redb METADATA table

Dependency Audit

Cargo Audit

Full scan of all 316 crate dependencies against the RustSec advisory database:

cargo audit
    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
    Scanning Cargo.lock for vulnerabilities (949 advisories)

    0 vulnerabilities found
    0 warnings found

Unmaintained Dependencies

One unmaintained dependency was found and resolved:

  • rustls-pemfile v1.0.4 (RUSTSEC-2025-0134) via reqwest v0.11.27
  • Fix: updated reqwest from v0.11.27 to v0.13.2

Unsafe Code Audit

Comprehensive scan of all source files across all UltraDAG crates:

CrateUnsafe Instances
ultradag-coin0
ultradag-network0
ultradag-node0
ultradag-sdk0
Total0

UltraDAG achieves 100% safe Rust — no unsafe blocks, no manual memory management, no undefined behavior risks.


Test Coverage

Test Breakdown

CategoryCount
Unit tests (ultradag-coin)168
Integration tests (ultradag-coin)407
Unit tests (ultradag-network)25
Integration tests (ultradag-network)12
Fault injection tests49
Jepsen fault injection14
Adversarial integration5
Simulation tests (ultradag-sim)64
RPC tests25
SDK tests146
Total1,000+

Jepsen Fault Injection

14 Jepsen-style tests validate consensus under adversarial conditions:

  • Split-brain partition with heal
  • Partition with clock skew recovery
  • Extreme chaos (combined faults)
  • Single and simultaneous node crashes
  • Repeated crash-restart cycles
  • Message chaos (delays, drops, reordering)
  • Future timestamp rejection
  • Minority partition liveness check

Simulation Harness

64 deterministic simulation tests run real consensus logic with a virtual network:

  • Base consensus convergence (100-1000 rounds)
  • Staking lifecycle with commission
  • Delegation rewards and splits
  • Governance parameter change execution
  • Epoch transitions
  • Equivocation detection under message reorder
  • 21-validator stress with 5% loss
  • Mixed Byzantine strategies (2/7 Byzantine)
  • Late-joiner convergence

Formal Verification

The consensus protocol is specified in TLA+ and model-checked:

  • 32.9 million states explored
  • 6 invariants verified with zero violations
  • Model: N=4 validators, 1 Byzantine, MAX_ROUNDS=2

See Formal Verification for full details.


Current Security Posture

AspectStatus
Cargo auditClean (0 vulnerabilities, 0 warnings)
Unsafe codeZero instances
Supply invariantFATAL on violation (exit code 101)
Transport encryptionAll P2P traffic encrypted (Noise protocol)
Rate limitingPer-IP, per-peer, per-endpoint
Formal verification32.9M states, zero violations
Test coverage900+ tests passing (core + sim)
Arithmetic safetySaturating operations throughout

Next Steps