RandProofRandProof
Whitepaper

29. Technical Audit Report

Audit Date: June 18, 2026 | Scope: Whitepaper v0.44 | Auditor: Internal Technical Review

Audit Date: June 18, 2026 | Scope: Whitepaper v0.44 | Auditor: Internal Technical Review

This section documents findings across five audit domains: (1) code and cryptographic correctness, (2) smart contract security vulnerabilities, (3) staking model integrity, (4) entropy source security and decentralization scoring, and (5) decentralization benchmarking against leading Web3 protocols. Each finding is classified as CRITICAL, HIGH, MEDIUM, LOW, or INFORMATIONAL.

29.1 Code & Cryptographic Correctness

29.1.1 Aggregation Formula: Findings

Finding C-01 [RESOLVED]: XOR Aggregation Replaced with Hash-Chain (Fixed in v3.8)

Previous formula (v3.7): combinedEntropy = drandEntropy ^ nistEntropy ^ ... ^ quicknetEntropy, XOR-based. This has been replaced in v3.8 with a keccak256 hash-chain that is entropy-preserving, non-invertible, and prevents cancellation. See Section 3.3 for the updated canonical formula.

XOR has a known weakness: if any two input sources produce identical values (even transiently due to misconfiguration or attack), their contributions cancel to zero. Additionally, XOR is not a cryptographic mixing function, two correlated sources do not increase entropy beyond the stronger one. The recommended fix is a sequential keccak256 hash-chain (fold) rather than XOR, which is both collision-resistant and entropy-preserving:

Recommended fix: bytes32 combined = keccak256(abi.encode(drandEntropy, nistEntropy, chainEntropy, participantEntropy, timeEntropy, randaoEntropy, btcEntropy, multiChainEntropy, qrngEntropy, torEntropy, babeEntropy, quicknetEntropy, requestId));

This is strictly more secure: it preserves all entropy from all sources, is non-invertible, and prevents cancellation. The whitepaper should present this as the canonical aggregation formula.

Finding C-02 [RESOLVED in v0.57]: Block Timestamp as Entropy Source is Miner-Biasable

Source 5 (Block Timestamp, 5% weight) can be manipulated by validators within a ~12-second window on Ethereum (and wider windows on some L2s/alt-chains). While the 5% weight limits blast radius, the whitepaper should explicitly note this limitation and add a tiebreaker protection note: timestamps should be hashed with the block hash, not used in isolation: timeEntropy = keccak256(abi.encode(block.timestamp, block.number, blockhash(block.number - 1))). Recommend upgrading the documented formula. Resolved in v0.57: the canonical Section 3.3 formula now applies this hardening.

Finding C-03 [RESOLVED]: Section 6.4 Lifecycle Formula Updated (Fixed in v3.8)

The PoFR Event Lifecycle in Section 6.4 still references only 5 entropy inputs in the message hash M:

Each keeper computes M = keccak256(abi.encode(chainId, address(this), eventId, drandEntropy, nistEntropy, chainEntropy, participantEntropy, timeEntropy, randaoEntropy, btcEntropy, multiChainEntropy, qrngEntropy, torEntropy, babeEntropy, quicknetEntropy, randProofVrfEntropy, autonomousBeaconEntropy, epochPoolEntropy))

The lifecycle formula in Section 6.4 has been updated in v3.8 to include all 15 entropy sources plus chainId and contract address in the BLS signing message M, preventing selective-source substitution and cross-chain replay attacks.

Finding C-04 [RESOLVED]: Section 7 Entropy Pipeline Updated (Fixed in v3.8)

The generatePoFREntropy() function in Section 7.1 has been updated in v3.8 with a v1.0 partial implementation disclaimer. The first 5 sources are shown for clarity; production code fetches all 15 sources. The BLS signing message M now references all entropy inputs per Section 6.4.

Finding C-05 [LOW]: participantEntropy = commitRevealXOR (raw XOR, no final hash)

The commit-reveal XOR aggregation is correct for combining participant secrets, but the last participant can bias the result by choosing their reveal value. The whitepaper acknowledges this in the limitations table but should document the standard mitigation: use a hash-then-XOR scheme and enforce a reveal deadline after which late reveals are excluded and replaced with the hash of committed values.

Finding C-06 [LOW]: keccak256(abi.encode(block.prevrandao)) is redundant wrapping

PREVRANDAO already returns a bytes32. Wrapping it in keccak256(abi.encode()) adds no entropy and minimal security benefit. Prefer using the value directly or documenting the reason for double-hashing (e.g., domain separation).

29.2 Smart Contract Security Vulnerabilities

Finding S-01 [RESOLVED]: transfer() Reentrancy Replaced with Pull-Payments (Fixed in v3.8)

The _distributeFee() function uses transfer() in a loop to pay keeper nodes. This pattern has two known issues: (1) transfer() forwards only 2,300 gas which will fail if any signer is a smart contract with a non-trivial receive() function, causing the entire fulfillment to revert and potentially causing a denial-of-service; (2) if any address is a contract that calls back into KeeperCoordinator during the transfer, reentrancy is possible.

Recommended fix: Use a pull-payment pattern (Checks-Effects-Interactions). Accumulate balances in a mapping and let keepers withdraw separately: pendingWithdrawals[signers[i]] += share; // then keepers call withdraw(). This eliminates both the gas limit issue and reentrancy vectors.

Finding S-02 [RESOLVED]: Division-by-Zero Guard Added (Fixed in v3.9.1)

The formula uint256 share = (keeperPool * stakes[signers[i]]) / totalSignerStake is correct in principle, but if totalSignerStake is 0 (e.g., all keepers unstaked between request and fulfillment), this causes a division-by-zero revert. Additionally, summing truncated shares may leave dust (wei) permanently locked in the contract. Add a guard: require(totalSignerStake > 0) and send any dust remainder to the gas pool.

**Finding S-03 [RESOLVED]: treasury.transfer() Replaced with call{value:} (Fixed in v3.8)**
If treasury is a multisig or contract, transfer() with 2,300 gas will revert. Use call{value: protocolCut}("") with a return value check, or a pull-payment pattern for the treasury address.

Finding S-04 [RESOLVED]: Fulfillment Timeout & cancelRequest() Added (Fixed in v3.8)

Section 19.1 now documents a cancelRequest() function with a 256-block timeout (~51 min on Base). If keepers fail to fulfill within the timeout window, the requester can call cancelRequest() to receive a full refund of their fee. This prevents permanently locked funds and provides a liveness guarantee for clients.

Finding S-05 [RESOLVED]: chainId + Contract Address Added to BLS Message M (Fixed in v3.8)

The BLS signing message M now includes chainId and address(this) as the first two fields (see updated Section 6.4): M = keccak256(abi.encode(chainId, address(this), eventId, ...all 15 entropy inputs...)). This prevents cross-chain signature replay. A valid aggregate signature from Chain A cannot be replayed on Chain B because chainId differs.

Finding S-06 [MEDIUM]: No On-Chain BLS Public Key Registry Integrity Check

The whitepaper references BLS key shares but does not specify how keeper BLS public keys are registered on-chain, updated, or revoked. If a keeper’s key share is compromised, there must be a mechanism to remove it without breaking the threshold. Recommend documenting a key rotation mechanism with a mandatory waiting period.

Finding S-07 [LOW]: gasPool += gasReserve accumulates but is never spent in documented code

The gas reserve pool accumulates 10% of every fee but the whitepaper does not document how it is drawn down. Add a withdrawGas(address keeper, uint256 amount) function with appropriate access controls (e.g., only callable by keepers with active stake to reimburse gas costs).

29.3 Staking Model: Integrity & Risk Analysis

Finding K-01 [RESOLVED]: Genesis Phase Federated Trust Model Disclosed (Fixed in v3.8)

At $20–60 minimum stake, a Sybil attacker can spin up 167–500 fake nodes for $10,000. While the whitepaper correctly argues this cannot affect entropy (the 15-source argument), it can affect liveness and consensus ordering. With t-of-n BLS where n=12 (genesis) and t=3, only 3 nodes need to sign. If an attacker controls 10 of 12 genesis nodes, they can:

  • Choose WHICH 3 keepers fulfill each request (winner selection for the signing round)

  • Selectively censor specific eventIds (grief specific clients)

  • Extract timing information about randomness commitments before on-chain settlement

Mitigation (Applied in v3.8): Section 24.1 now explicitly discloses: "Phase 0 (Genesis) operates under a federated trust model. This is NOT a decentralized phase. Full permissionless decentralization begins at Phase 2." The threat matrix and decentralization benchmarking section (29.5) already reflected this, and the whitepaper now carries a clear disclaimer in the genesis configuration section.

Finding K-02 [MEDIUM]: Slashing 100% for Double-Signing is Disproportionate for Honest Errors

100% slash for double-signing is common in PoS chains but may be too aggressive for an oracle network where double-signs can occur due to software bugs or network partitions (not just malicious behavior). Chainlink uses reputation-based slashing without total loss. Recommend: 50% slash for first double-sign offense + temporary ban; 100% for repeated offenses. This prevents good-faith node operators from being wiped out by infrastructure failures.

Finding K-03 [RESOLVED in v0.57]: Polkadot Minimum Stake ($3–5 DOT) is Significantly Under-Priced

DOT is a high-value chain (currently $6/DOT). 0.5 DOT = $3. This is the lowest minimum stake in the table by a factor of 10x and provides essentially no Sybil resistance on Polkadot specifically. Recommend: minimum 5 DOT ($30) to align with other chain tiers. Resolved in v0.57: the Section 21.1 table now specifies 5 DOT ($30), restoring the ~$20-and-above USD floor assumed by the Sybil-cost analysis in Section 23.2.2.

Finding K-04 [LOW]: No Slashing for Incorrect Entropy Submission

The slashing rules cover double-signing, offline nodes, invalid signatures, and Byzantine behavior, but not submitting incorrect entropy values (e.g., a stale DRAND round, wrong NIST timestamp). Add a slash condition for provably incorrect entropy submissions verifiable on-chain.

Finding K-05 [LOW]: Mobile Light Nodes Have No Staking Requirement

Mobile light nodes can earn 2–5% fees with zero staking. This creates a low-cost spam vector for gossip relay and commit-reveal entropy. Recommend: require a nominal deposit ($1–5) refundable after a minimum active period to deter pure spam participation.

29.4 Entropy Source Security & Decentralization Analysis

The following table scores each entropy source across four dimensions: Decentralization (1–10), Attack Cost (estimated), Availability (uptime reliability), and Independence (correlation with other sources in the stack).

● Source 1: DRAND Mainnet (20%)

22 LoE nodes; BLS threshold; battle-tested 4+ years. Decentralization: 8/10. Attack cost: $500M+. Availability: 99.9%+. Independence: High. Weakness: Permissioned LoE membership.

● Source 2: Chain-Native VRF (10%)

Chain-specific (varies by chain). On Ethereum: 1M+ validators. Decentralization: 9/10. Attack cost: $50B+ (ETH). Availability: 99.9%. Independence: High. Weakness: Chain-dependent; on PoA chains this degrades significantly.

● Source 3: Commit-Reveal (10%)

User-sourced. Decentralization: 10/10 (anyone participates). Attack cost: Scales with participation. Availability: Dependent on user activity. Independence: Unique, only user-sourced entropy in the stack. Weakness: Last-revealer bias (documented); low-participation raffles are vulnerable.

Source 4: NIST Beacon (5%)

U.S. government-operated. Decentralization: 2/10 (single operator). Attack cost: Nation-state level. Availability: 99%+. Independence: High (off-chain, non-blockchain). Weakness: Single point of control; not suitable as primary source (correctly weighted at 5%).

Source 5: Block Timestamp (5%)

Validator-controlled within window. Decentralization: 7/10. Attack cost: 51% attack on chain. Availability: 100%. Independence: Correlated with Source 2 on same chain. Weakness: ~12s manipulation window; should be combined with block hash (see C-02).

Source 6: Ethereum RANDAO (5%)

ETH PoS PREVRANDAO opcode. Decentralization: 9/10 (1M+ validators). Attack cost: $50B+. Availability: 100%. Independence: Correlated with ETH block production (Source 2 if using ETH). Weakness: Lookahead bias, proposers know RANDAO 1 epoch ahead. Not suitable as sole source for high-value selections.

Source 7: Bitcoin Merkle Root (5%)

Bitcoin PoW. Decentralization: 8/10. Attack cost: $50B+ hash rate. Availability: 99.9%. Independence: High (completely separate network). Weakness: ~10 minute update frequency; keepers must wait for BTC confirmation. Latency concern for fast raffles.

Source 8: Multi-Chain Block Hashes (5%)

Aggregated from multiple chains. Decentralization: 9/10. Attack cost: Must attack all chains simultaneously. Availability: Varies by chain. Independence: Partially correlated if chains share validators (e.g., EVM L2s share ETH security). Weakness: If all sourced chains are EVM/ETH-based, correlation risk exists.

Source 9: ANU QRNG (5%)

Academic quantum hardware. Decentralization: 3/10 (2 providers). Attack cost: Physical access to hardware. Availability: ANU QRNG has had historical downtime; fallback is required. Independence: Highest, physically isolated quantum process. Weakness: Single-institution fallback risk; HTTP API dependency.

Source 10: Tor Consensus Hash (5%)

9 directory authorities. Decentralization: 7/10. Attack cost: $100M+ (5-of-9 compromise). Availability: 99%+. Independence: High (network layer, not blockchain). Weakness: Hourly update only, introduces a replay window for events within the same hour. Not suitable for sub-hourly fairness proofs without additional measures.

Source 11: BABE VRF (5%)

Polkadot validators (~300 active). Decentralization: 8/10. Attack cost: $500M+ (66%+ of DOT stake). Availability: 99%+. Independence: High (completely separate from ETH validator set). Weakness: ~4 hour epoch means randomness is predictable 2 epochs in advance (N-2 design). Keepers must document which epoch they commit to.

Source 12: drand Quicknet (5%)

League of Entropy (same org as Source 1, different chain). Decentralization: 8/10. Attack cost: $500M+. Availability: 99.9%+. Independence: PARTIAL, same LoE members as Source 1. If LoE is compromised, BOTH Sources 1 and 12 fail simultaneously. This is the most significant entropy correlation risk in the stack.

Finding E-01 [RESOLVED]: LoE Shared Trust Root Disclosed (Fixed in v3.8)

Both Source 1 and Source 12 are operated by the League of Entropy (LoE). If the LoE is compromised, both sources fail simultaneously, effectively reducing the stack from 15 independent sources to 13. This is now explicitly disclosed in Section 3.3 after Source 12. Combined weight of 25% (20% + 5%) on LoE-controlled sources means LoE compromise has a 25% direct impact on the combined entropy output. The remaining 75% of entropy from 13 independent sources remains uncompromised.

Recommendation: Either (a) reduce combined LoE weight to 25% (already reduced from 30% in v3.1) to a truly independent source (e.g., Competitor VRF or Verifiable Delay Function), or (b) explicitly disclose the shared trust root and note it as a known concentration.

Finding E-02 [MEDIUM]: BABE VRF N-2 Lookahead is a Known Predictability Concern

Polkadot BABE announces epoch randomness 2 epochs in advance (~8 hours). This means an attacker who can read on-chain data knows the BABE contribution to the entropy stack up to 8 hours before it is “used.” For high-value raffles, this is a meaningful pre-image availability window. Recommend: explicitly document that BABE entropy is not used until the target epoch is finalized, and that the commitment to BABE entropy occurs at request time (not fulfillment time).

Finding E-03 [MEDIUM]: Multi-Chain Block Hashes (Source 8) Has EVM Correlation Risk

If the multi-chain hashes are sourced primarily from EVM chains that share Ethereum’s security model (Base, OP, ARB, Linea), they are not truly independent entropy, they all derive from Ethereum L1. The whitepaper should specify which chains are included and require at least one non-EVM chain (e.g., Solana, Cardano) in the multi-chain hash set.

Finding E-04 [LOW]: No Staleness / Freshness Checks Documented for Off-Chain Sources

Sources 4 (NIST), 9 (ANU QRNG), and 10 (Tor) are fetched via HTTP. The whitepaper does not specify maximum acceptable staleness windows. A keeper that submits a 24-hour-old NIST value should be rejected. Recommend documenting maximum staleness: NIST `≤` 60 seconds, ANU QRNG `≤` 30 seconds, Tor consensus `≤` 65 minutes (one update cycle + buffer).

29.5 Decentralization Benchmarking vs. Leading Web3 Protocols

The Nakamoto Coefficient measures the minimum number of entities that must collude to compromise a system (higher = more decentralized). Node count and minimum stake are also key decentralization indicators.

Ethereum (validators): 1,000,000+ nodes | Nakamoto Coefficient: 4 entities (Lido/CEX concentration) | Min stake: $102,400 (32 ETH) | Permissionless; high stake barrier | Decentralization score: 6/10 (stake concentration)

Competitor VRF: ~200 nodes | Nakamoto Coefficient: 31 (permissioned whitelist) | Min stake: $7,500 | Permissioned admission by Chainlink Labs | Decentralization score: 4/10

Pyth Network: ~90 nodes | Nakamoto Coefficient: ~20 | Min stake: $0 (invited only) | First-party publishers; whitelist | Decentralization score: 3/10

API3: ~87 nodes | Nakamoto Coefficient: ~10 | Min stake: ~$1,000 | First-party oracles; small set | Decentralization score: 3/10

UMA (optimistic): ~150 nodes | Nakamoto Coefficient: ~15 | Min stake: ~$200 | Dispute-only model | Decentralization score: 5/10

DRAND (LoE): 22 nodes | Nakamoto Coefficient: 12 | Min stake: $0 (invited) | Permissioned LoE membership | Decentralization score: 5/10

Gelato Network: ~18 nodes | Nakamoto Coefficient: ~5 | Min stake: ~$50 | Semi-permissioned executors | Decentralization score: 3/10

RandProof (Genesis/Phase 0): 12 nodes | Nakamoto Coefficient: 4 (t=3 threshold) | Min stake: $20–60 | Founder-controlled bootstrap phase | Decentralization score: 2/10 (federated)

RandProof (Phase 2 target): 25 nodes | Nakamoto Coefficient: 9 | Min stake: $20–60 | Permissionless; audit complete | Decentralization score: 5/10

RandProof (Phase 4 target): 1,000+ nodes | Nakamoto Coefficient: 334+ (t=~1/3) | Min stake: $20–60 | Permissionless; lowest barrier of any oracle | Decentralization score: 9/10 (projected)

Key Observations:

  • RandProof Phase 4 (1,000+ nodes, $20 minimum stake) would have the LOWEST barrier to entry of any oracle or randomness protocol currently in production, lower than Chainlink ($7,500), API3 ($1,000+), and Ethereum ($102,400).

  • RandProof Phase 4 Nakamoto Coefficient (~334) would exceed Ethereum (4) and all current oracle protocols, making it the most decentralized oracle network by this metric at target scale.

  • The Genesis phase (12 nodes, founder-controlled) has a Nakamoto Coefficient of 4 (t=3 of 12). This is LOWER than all mature protocols and must be clearly disclosed as a bootstrap phase, not a decentralization claim.

  • Chainlink's permissioned node set (whitelist) is a structural centralization vector that RandProof eliminates by design. This is a legitimate and significant competitive differentiator.

  • drand LoE (22 nodes, permissioned) underpins Sources 1 and 12 combined. RandProof's claim of 15 independent sources partially overstates independence due to this shared trust root.

29.6 Audit Summary & Remediation Priority

[RESOLVED] S-01: transfer() loop reentrancy in _distributeFee()

Fix: Replace with pull-payment pattern before mainnet

[RESOLVED] C-01: XOR aggregation replaced with keccak256 hash-chain

Fix: Replace with hash-chain (keccak256 fold) formula

[RESOLVED] S-02: Division-by-zero guard added (require totalSignerStake > 0)

Fix (Applied in v3.9.1): require(totalSignerStake > 0) guard added before fee distribution loop. Dust remainder routed to gas pool.

[RESOLVED] S-03: treasury.transfer() replaced with call{value:}
**Fix:** Use call{value:} with return check

[RESOLVED] K-01: Genesis federated trust model disclosed in Section 24.1

Fix: Disclose as bootstrap phase; update threat matrix

[RESOLVED] E-01: LoE shared trust root disclosed in Section 3.3

Fix: Disclose shared operator; reduce combined weight or add independent source

[MEDIUM] C-02: Block timestamp miner-biasable

Fix: Add blockhash to timestamp entropy

[RESOLVED] C-03: Section 6.4 updated to include all 15 sources + chainId

Fix (Applied in v3.8): M updated to include all 15 entropy inputs plus chainId and contract address

[RESOLVED] C-04: Section 7 updated with v1.0 partial implementation disclaimer

Fix: Update function or add v1.0 disclaimer

[RESOLVED] S-04: cancelRequest() with 256-block timeout added

Fix: Add cancelRequest() with timeout

[RESOLVED] S-05: chainId + contract address added to BLS message M

Fix: Include chainId + contract address in message M

[MEDIUM] S-06: No BLS key rotation mechanism documented

Fix: Document key rotation protocol

[MEDIUM] K-02: 100% slash for double-sign too aggressive for honest errors

Fix: Tiered slashing: 50% first offense, 100% repeat

[MEDIUM] K-03: Polkadot stake ($3–5) severely under-priced

Fix: Raise to 5 DOT minimum (~$30)

[MEDIUM] E-02: BABE VRF 8h lookahead window

Fix: Document commitment timing; use finalized epoch only

[MEDIUM] E-03: Multi-chain hashes may all be EVM-correlated

Fix: Require at least 1 non-EVM chain in hash set

[LOW] C-05: Last-revealer commit-reveal bias

Fix: Document reveal deadline + hash-then-XOR mitigation

[LOW] C-06: Redundant keccak256 wrapping of PREVRANDAO

Fix: Document reason or simplify

[LOW] S-07: gasPool never drawn down in documented code

Fix: Document withdrawGas() function

[LOW] K-04: No slash for incorrect entropy submission

Fix: Add entropy correctness slash condition

[LOW] K-05: Mobile light nodes have zero stake requirement

Fix: Add $1–5 nominal deposit

[LOW] E-04: No staleness windows documented for HTTP sources

[PRE-MAINNET] External Security Audit Required

Action: Engage Trail of Bits, OpenZeppelin, or CertiK for full external audit before mainnet

Fix: Document max staleness: NIST 60s, ANU 30s, Tor 65min

Overall Assessment: RandProof's multi-source entropy architecture is genuinely innovative and technically sound at the protocol design level. The 15-source entropy stack provides industry-leading theoretical attack cost. However, several smart contract implementation patterns (transfer() loops, XOR aggregation, missing staleness checks) must be addressed before mainnet deployment. The most important non-code fix is accurate disclosure of the genesis phase trust model and the LoE shared trust root across Sources 1 and 12. With these remediations applied, RandProof would represent the most decentralized, lowest-barrier, and most entropy-diverse randomness oracle currently documented in the Web3 space.

⚠ EXTERNAL SECURITY AUDIT REQUIRED

The internal technical audit in Section 29 identifies and documents findings across five domains. However, an internal audit is not a substitute for an independent external security review. Before mainnet deployment, RandProof Network must engage a reputable external security firm (e.g., Trail of Bits, OpenZeppelin, CertiK, ConsenSys Diligence) to conduct: (1) full smart contract audit of KeeperCoordinator.sol and all periphery contracts, (2) cryptographic review of the BLS threshold signing implementation and entropy aggregation, (3) threat model validation of the keeper network consensus and gossip protocol, (4) economic security review of the staking and slashing model. The external audit report must be published publicly and findings addressed before Phase 1 mainnet launch.

29.7 Adversarial White Hat Audit: Attack Vectors & Mitigations (v3.9.2)

This section documents a red-team adversarial audit conducted on v3.9.1, simulating sophisticated attacker strategies to manipulate randomness outcomes, steal funds, DoS the network, or undermine protocol trust. Each attack vector is analyzed for feasibility across deployment phases, with mitigations applied where critical.

AV-01 [MEDIUM→LOW]: Keeper-Controlled Entropy Grinding (Sources 13-15)

Attack: During genesis (12 nodes, t=3), an attacker controlling the signing threshold controls Sources 13-15 (RandProofVRF, Autonomous Beacon, Epoch Entropy Pool). They could attempt to grind multiple entropy combinations to produce a favorable outcome.

Analysis: With the hash-chain formula, each combination of sources 13-15 produces a unique keccak256 output. The search space per grinding attempt is 2^96 per source (BLS12-381 VRF output). Even with 3 controlled sources, the attacker must compute keccak256(abi.encode(s1...s15)) for each attempt and check if the resulting seed produces their desired winnerIndex. At 2^288 search space (3 × 2^96), this is computationally infeasible.

Mitigation: The grinding risk is theoretically negligible due to the hash-chain construction. At Phase 4 (1,000+ nodes), controlling the signing threshold becomes economically impractical. No code fix required, this finding is documented for completeness.

Status: DOCUMENTED, Risk is computationally infeasible. No code fix needed.

AV-02 [HIGH→RESOLVED]: Race Condition in BLS Aggregation, Entropy Value Divergence

Attack: The first keeper to aggregate t=3 BLS signatures collects signatures from other keepers via gossip. A malicious aggregator could feed different entropy values for Sources 13-15 to different keepers via the gossip network, causing each keeper to sign a different message M. The aggregator then submits the combination that produces their preferred outcome.

Root Cause: The fulfill() function receives the seed OUTPUT, not the entropy INPUTS. The contract verifies the BLS aggregate signature but cannot verify that all signers committed to the SAME entropy values for protocol-native sources.

Fix Applied in v3.9.2: The fulfill() function signature is updated to accept entropy inputs alongside the BLS proof: fulfill(eventId, bytes32[15] memory entropyInputs, bytes memory aggregatedSig, address[] memory signers). The contract verifies the BLS aggregate signature against M = keccak256(abi.encode(chainId, address(this), eventId, entropyInputs[0..14])). This ensures all signers committed to the SAME entropy values, if any signer used different values, their signature component won't verify in the aggregate.

Status: RESOLVED, fulfill() now accepts and verifies entropy inputs against the BLS aggregate signature.

AV-03 [CRITICAL→RESOLVED]: No On-Chain Verification of External Entropy Values

Attack: Keepers fetch external entropy (DRAND, NIST, Bitcoin, ANU QRNG, Tor) off-chain and submit the result on-chain. The contract verifies the BLS signature (proving 3 keepers AGREED on the values) but does NOT verify that the values are the ACTUAL outputs from those external sources. If 3 keepers collude, they can submit completely fabricated entropy for all 15 sources and produce any seed they want. The $100B+ attack cost claim assumes entropy integrity, but without on-chain verification, the actual attack cost drops to 'cost of 3 keeper nodes at genesis' = $60-180.

Root Cause: BLS signature proves agreement, not truth. The chain of trust has no on-chain verification of external entropy values.

Fix Applied in v3.9.2: Four-Layer Entropy Verification Architecture:

Layer 1: On-Chain Verification (Mandatory): The contract independently verifies entropy values that can be verified on-chain:

• Source 1 (DRAND): BLS signature verification against DRAND public key on-chain (via drand evmnet BN254 precompile). Cost: ~45,000 gas.

• Source 6 (Ethereum RANDAO): Read block.prevrandao opcode directly. Cost: 0 gas (already on-chain).

• Source 5 (Block Timestamp): Read block.timestamp directly. Cost: 0 gas (already on-chain).

• Source 13 (RandProofVRF): BLS threshold VRF proof verified on-chain (already protocol-native). Cost: ~45,000 gas.

• Source 14 (Autonomous Beacon): VDF proof verified on-chain (already protocol-native). Cost: ~20,000 gas.

• Source 15 (Epoch Entropy Pool): Read from on-chain EpochPool contract. Cost: 0 gas (already on-chain).

Layer 2: Multi-Keeper Attestation (Mandatory): For off-chain sources that cannot be verified on-chain (NIST, Bitcoin Merkle Root, ANU QRNG, Tor Consensus, Multi-Chain Block Hashes, BABE VRF, drand Quicknet), the protocol requires at least 2 INDEPENDENT keepers to submit matching entropy values. If submitted values diverge, the event is flagged for review and only on-chain-verifiable sources are used (with a proportional weight adjustment). This means a single malicious keeper cannot fabricate entropy, they need at least one other independent keeper to submit the same fake values.

Implementation: Each keeper submits entropy values via submitEntropy(eventId, sourceId, value, proof). The contract records the first submission and requires a matching submission from a different keeper before the values are accepted. Non-matching submissions trigger a dispute flag.

Layer 3: Fraud-Proof Challenge Window (Mandatory): After fulfillment, there is a 24-hour challenge window (~20 seconds on Base). During this window, any keeper or observer can submit a fraud proof for unverifiable off-chain sources:

• DRAND fraud proof: Submit the correct DRAND signature for the claimed round. Verified on-chain via BLS.

• NIST fraud proof: Submit the correct NIST pulse value + ECDSA signature. Verified on-chain.

• Bitcoin fraud proof: Submit an SPV proof (Merkle path) for the claimed block hash.

If a fraud proof verifies, the fulfillment is invalidated, the dishonest keepers are slashed 100%, and the event is re-fulfilled with correct entropy.

Layer 4: Economic Slashing for False Entropy (Mandatory): Any keeper proven to have submitted false entropy (via on-chain verification failure or successful fraud proof) receives 100% stake loss + permanent ban. This makes the cost of lying economic death, not just 'oops, try again.' Combined with Layer 2 (multi-keeper attestation), an attacker must control at least 2 independent keepers AND prevent any fraud proof during the challenge window, dramatically raising the attack cost.

Status: RESOLVED, Four-layer entropy verification architecture documented. On-chain verification for 6 of 15 sources, multi-keeper attestation for 9 off-chain sources, fraud-proof challenge window, and economic slashing for false submissions.

AV-04 [MEDIUM→RESOLVED]: Fulfill Frontrunning / MEV

Attack: A keeper submits a fulfill() transaction to the public mempool. A validator or MEV searcher sees the pending transaction, extracts the seed, and can censor it if the outcome is unfavorable. Since block.timestamp and block.prevrandao change per block, a validator could censor fulfill transactions until entropy produces their desired winner.

Fix Applied in v3.9.2: Fulfill transactions are submitted via private mempool (Flashbots Protect on Ethereum L1, MEV-Share on L2s) to prevent mempool visibility. Additionally, the commit-reveal pattern is applied to fulfillment: keepers first submit a commitment hash commitHash = keccak256(seed, salt) on-chain, then reveal the seed and salt after the commitment block is finalized. The contract verifies the reveal matches the commitment. This prevents validators from seeing the seed before it's committed.

Status: RESOLVED, Private mempool submission + commit-reveal fulfillment pattern documented.

AV-05 [MEDIUM→RESOLVED]: Stale Entropy Replay

Attack: A keeper fetches entropy at block N but the fulfill transaction fails. The keeper retries at block N+10 with the SAME external entropy values (DRAND round, NIST pulse, BTC merkle root haven't changed) but new on-chain values (timestamp, prevrandao). The keeper 'shops' for favorable block conditions by holding external entropy constant.

Fix Applied in v3.9.2: The fulfill() function now requires an entropyBlock parameter. The contract verifies: (1) requestBlock[eventId] <= entropyBlock <= block.number, (2) block.timestamp at entropyBlock matches the submitted timeEntropy, (3) block.prevrandao at entropyBlock matches the submitted randaoEntropy (via BLOCKHASH lookup). This binds the entropy to a specific block and prevents cross-block shopping.

Status: RESOLVED, Entropy block commitment prevents stale entropy replay.

AV-06 [LOW→DOCUMENTED]: Commit-Reveal Last-Revealer Bias

Attack: The last participant in a commit-reveal cycle can see all previous reveals and choose their value to bias the XOR result.

Mitigation Documented in v3.9.2: The commit-reveal scheme now enforces a reveal deadline. After the deadline, late reveals are excluded and replaced with keccak256(committedHash). This eliminates the last-revealer advantage. Additionally, with the hash-chain aggregation formula, the commit-reveal XOR is hashed with 14 other sources, reducing the bias impact to 1/15 of the total entropy.

Status: DOCUMENTED, Reveal deadline + hash-then-XOR mitigation documented.

AV-07 [MEDIUM→RESOLVED]: BLS Key Rotation Gap

Attack: An attacker who compromises a keeper's BLS private key can sign fulfill transactions until the key is rotated. The whitepaper mentioned rotation but did not document the on-chain mechanism.

Fix Applied in v3.9.2: The contract now documents a rotateBLS(newPubkey) function with a 24-hour timelock delay. During the timelock, both old and new keys are active. After 24h, the old key is automatically revoked. An emergency slashAndRotate(keeperAddress) function allows other keepers to revoke a compromised key immediately with a 5-of-12 multi-sig threshold during genesis, and t/2 threshold at Phase 2+.

Status: RESOLVED, On-chain BLS key rotation with timelock + emergency revocation documented.

AV-08 [MEDIUM→DOCUMENTED]: Treasury Centralization

Attack: 20% of all protocol revenue goes to treasury. If treasury is an EOA controlled by the founder, this is a centralized financial vector. If compromised, an attacker drains accumulated protocol revenue.

Mitigation (Target Structure, See AV-50 for Current State): The planned treasury structure is a Gnosis Safe multisig (3-of-5 threshold) during Genesis and Phase 2, transitioning at Phase 4 to a timelocked governance contract with a 7-day execution delay and community-elected signers. Treasury signers and addresses will be published at randproof.network/treasury once that multisig is actually constituted. As of this writing, the treasury is held under single-founder custody rather than this target multisig, see AV-50 for the honest current-state disclosure. The goal of preventing any single party from unilaterally withdrawing treasury funds is not yet met during the current single-founder phase.

Status: DOCUMENTED, Target treasury governance structure disclosed (3-of-5 multisig → timelocked governance); current single-founder custody disclosed honestly in AV-50 rather than implied resolved.

AV-09 [HIGH→DOCUMENTED]: Genesis Liveness / Gatekeeping Attack

Attack: During genesis (12 nodes, t=3), an attacker controlling 10 of 12 nodes can: choose which 3 keepers sign each event, censor specific events, and extract timing information. While they cannot manipulate the randomness output (external entropy sources remain secure), they can attack liveness and event ordering.

Mitigation Documented in v3.9.2: The genesis phase implements a rotating signing committee: for each event, the 3 signers are deterministically selected based on the previous block's hash, not chosen by the aggregator. A keeper selected to sign who refuses is logged as a missed signature with a 10% slashing penalty per missed event (up to 50% cumulative before temporary ban). This eliminates the gatekeeping attack, no single party chooses which keepers sign. Additionally, the Phase 0 federated trust disclosure (Section 24.1) explicitly warns that genesis is not decentralized.

Status: DOCUMENTED, Rotating signing committee + missed-signature slashing eliminates gatekeeping.

AV-10 [INFO]: Modulo Bias in Winner Selection

Attack: uint256(seed) % totalEntrants has a theoretical modulo bias when totalEntrants is not a power of 2. The bias is ~1/2^256 per selection, computationally irrelevant but relevant for compliance contexts.

Mitigation Documented in v3.9.2: For compliance-critical use cases (government lotteries, clinical trials, legal proceedings), the protocol offers a rejection sampling option: if (uint256(seed) >= totalEntrants * (type(uint256).max / totalEntrants)) { request new seed; } else { winnerIndex = uint256(seed) % totalEntrants; }. This eliminates all modulo bias at the cost of an occasional retry (~1 in 2^128 events). The standard mode (direct modulo) is documented as having negligible bias suitable for Web3 gaming, NFT mints, and raffles.

Status: DOCUMENTED, Rejection sampling option documented for compliance use cases.

AV-11 [NONE]: cancelRequest() Reentrancy, No Issue Found

Attack: A malicious client contract with a reentrant receive() function could attempt to re-enter cancelRequest() during the refund call.

Analysis: The contract sets eventFees[eventId] = 0 BEFORE the call (Checks-Effects-Interactions pattern). Re-entering for the same eventId returns 0 refund. Re-entering for a different eventId is fine, each event has independent state. The pull-payment pattern for keepers is also safe. No vulnerability found.

Status: NO ISSUE, CEI pattern correctly followed.

AV-12 [CRITICAL→RESOLVED]: Client Contract Blind Trust (Same Root Cause as AV-03)

Attack: The client integration example shows require(msg.sender == address(coordinator)) in fulfillRandomness(), but the client contract cannot independently verify entropy. If a malicious keeper submits fake entropy, the coordinator calls fulfillRandomness() with a bad seed, and the client trusts it.

Fix: Resolved by AV-03's four-layer entropy verification architecture. With on-chain verification (Layer 1), multi-keeper attestation (Layer 2), fraud-proof challenge window (Layer 3), and economic slashing (Layer 4), the entropy values submitted to the coordinator are now independently verifiable. Client contracts can optionally call getEntropyInputs(eventId) to retrieve the verified entropy inputs and perform their own validation.

Status: RESOLVED, Same fix as AV-03. Client contracts can access verified entropy inputs.

Adversarial Audit Summary

Critical findings (AV-03, AV-12) addressed via four-layer entropy verification architecture. High findings (AV-02, AV-09) addressed via entropy-input verification in fulfill() and rotating signing committee. Medium findings (AV-04, AV-05, AV-07) addressed via private mempool + commit-reveal, entropy block commitment, and on-chain BLS key rotation. Low/Info findings (AV-06, AV-08, AV-10) documented with mitigations.

Key Insight: The adversarial audit revealed that the protocol's theoretical security model ($100B+ attack cost) was overstated without on-chain entropy verification. With the four-layer architecture applied in v3.9.2, the security claim is now backed by on-chain verification for 6 of 15 sources, multi-keeper attestation for 9 off-chain sources, fraud-proof challenge windows, and economic slashing for false submissions. This closes the specific gap this finding identified (fabricated entropy from collusion among 3 keepers). It does not by itself mean the full $100B+ figure applies today: that figure is the Phase 4 target once all 15 sources are live and the keeper set is fully decentralized (see Section 26). At earlier phases, fewer sources are active and the federated genesis keeper set (Section 24.1) is a separate, smaller trust assumption that this fix does not eliminate.

29.8 Adversarial White Hat Audit: Round 2 (v3.9.3)

Round 2 of the adversarial audit focused on attack surfaces not covered in Round 1: the gossip/P2P layer, mobile light nodes, bridge/settlement risk, software supply chain, VDF/epoch edge cases, BLS verification on non-EVM chains, and economic edge cases. 12 additional attack vectors identified and mitigated.

AV-13 [HIGH→RESOLVED]: Mobile Light Node Entropy Poisoning

Attack: An attacker spins up 1,000 mobile light node instances on cloud emulators at $0.01 each. Each submits plausible but slightly wrong entropy values (off-by-one DRAND round, stale NIST pulse) to the keeper gossip layer. If keepers use majority voting from light node submissions, the attacker can bias Source 4 (Commit-Reveal, 10% weight).

Fix Applied in v3.9.3: (1) Light node entropy submissions are now ADVISORY ONLY, keepers must independently verify all external entropy values themselves, not trust light node submissions. (2) Light node entropy is NOT incorporated into Source 4 (commit-reveal pool), it serves as a separate verification input only. (3) Rate-limited to 1 submission per source per round per light node. (4) Light nodes that submit values mismatching verified entropy 3 times are auto-banned. (5) The commit-reveal pool (Source 4) is now restricted to registered keeper nodes only, not light nodes.

Status: RESOLVED, Light node entropy is advisory-only, rate-limited, and excluded from commit-reveal pool.

AV-14 [HIGH→RESOLVED]: Gossip Network Eclipse Attack

Attack: An attacker runs 50 keeper nodes and becomes gossip peers to legitimate keepers. By surrounding a target keeper with only attacker-controlled peers (eclipse attack), the attacker can feed fake entropy values, withhold BLS signatures, and delay event detection. With 12 genesis nodes and 5 gossip peers each, controlling 10 nodes is sufficient to eclipse any single keeper.

Fix Applied in v3.9.3: (1) Gossip peer selection is now deterministic from the on-chain keeper registry, peers are selected by blockhash-based randomization, not attacker-controlled connections. (2) During Genesis (12 nodes), every keeper connects to ALL other keepers (n-1=11 peers), not just 5. GOSSIP_PEERS is set to n-1 at genesis. (3) Minimum peer diversity: at least 2 peers must be from different registration blocks/stake epochs. (4) Alert triggers if >60% of gossip peers share the same IP range or ASN. (5) DHT-based peer discovery via on-chain keeper registry, keepers discover each other through chain data, not arbitrary P2P connections.

Status: RESOLVED, Deterministic peer selection, full mesh at genesis, diversity requirements documented.

AV-15 [MEDIUM→SUPERSEDED]: Wormhole Bridge Risk for Treasury Settlement

Attack: 20% of protocol revenue on non-CCTP chains (BNB, Avalanche, Moonbeam, Sui, Cardano, TON, Polkadot) is bridged to Base via Wormhole. Wormhole was hacked for $320M in February 2022. If Wormhole is compromised, treasury revenue from 7+ chains is lost or stuck.

Mitigation Documented in v3.9.3 (Superseded by AV-49 in v3.9.5): The v3.9.3 mitigation disclosed Wormhole as a risk and added a 24-hour timelock plus a LayerZero fallback, while still routing treasury funds through Wormhole by default. The external white-hat review that produced AV-48 through AV-50 (Section 29, Round 5) concluded that disclosure and a timelock reduce response time but do not eliminate exposure to funds already in transit inside the bridge. RandProof's adopted policy as of v3.9.5 removes the bridge from the treasury path entirely: see AV-49 for the current settlement policy (native USDC via CCTP V2 where available; native chain asset, no bridge, everywhere else).

Status: SUPERSEDED by AV-49: Wormhole is no longer part of RandProof's treasury settlement path. See AV-49 (Section 29, Round 5) for the current, adopted native-asset settlement policy.

AV-16 [CRITICAL→RESOLVED]: NPM Supply Chain Attack on @randproof/cli

Attack: The node setup includes npm install -g @randproof/cli. A compromised or typosquatted npm package (e.g., @randpro0f/cli) with a postinstall script can exfiltrate the .env file, BLS keystore, and EVM private key. This has happened to many Web3 projects (event-stream, ua-parser-js, coa). A single compromised package gives the attacker every node operator's BLS private keys, bypassing all 4 layers of entropy verification because the attacker holds legitimate keys. # ⚠ Pin version: npm install -g @randproof/cli@1.0.3: verify SHA-256 at randproof.network/downloads

Fix Applied in v3.9.3: (1) Docker is the ONLY recommended distribution path, CLI is for convenience only and carries a documented warning. (2) npm package versions are pinned with SHA-256 hash verification published at randproof.network/downloads. (3) npm provenance attestation via Sigstore (npm publish --provenance). (4) No postinstall scripts in the package, package.json scripts field is empty. (5) GPG-signed releases with published checksums on the official website. (6) Documented warning: 'Never install @randproof/cli on a machine with existing BLS keys. Always use Docker on production nodes.' (7) Typosquat monitoring: @randproof, @rand-proof, @rand_pro0f, @randpro0f variants are registered as squatter protection.

Status: RESOLVED, Docker-only distribution, pinned hashes, Sigstore provenance, no postinstall scripts, typosquat protection.

AV-17 [HIGH→RESOLVED]: Mobile-to-Desktop Remote Action Hijacking

restart node, rotate BLS key (24h timelock + desktop confirmation required), add/remove chains (desktop confirmation required), update RPC endpoints. All destructive actions require dual confirmation (mobile + desktop). Rate limited to 1 action per hour. (AV-17 fix)

Fix Applied in v3.9.3: (1) BLS key rotation from mobile requires the same 24-hour timelock as on-chain rotation, mobile initiates the request, key doesn't rotate for 24 hours, giving the operator time to notice and cancel. (2) Emergency pause from mobile can ONLY pause, resume requires desktop-side confirmation within 5 minutes. (3) 6-digit PIN replaced with QR-code-only exchange (no manual PIN entry), eliminates shoulder-surfing. (4) Rate-limit: max 1 remote action per hour from mobile. (5) Destructive actions (BLS rotation, chain removal, unstake) require BOTH mobile initiation AND desktop confirmation within 5 minutes, dual confirmation for all state-changing operations.

Status: RESOLVED, Dual confirmation, timelock on key rotation, QR-only pairing, rate limiting.

AV-18 [MEDIUM→RESOLVED]: Epoch Entropy Pool Bootstrap Problem

Attack: When the protocol launches, epochPool_0 must be initialized. If set by the founder or to 0x0, an attacker who knows the initial value can precompute future epoch pool values. During the first epoch with very few events, an attacker who participates in those 1-2 events can influence the epoch pool for epoch 1, affecting all events in that epoch.

Fix Applied in v3.9.3: (1) epochPool_0 is initialized as keccak256(blockhash(deploymentBlock + 256)), using a future blockhash that cannot be known at deployment time. (2) During Epoch 0 (first hour after launch), the Epoch Entropy Pool has reduced weight (2.5% instead of 5%) until a minimum of 10 PoFR events have accumulated. (3) After 10 events, full 5% weight is restored. (4) Documented: 'During Epoch 0, the Epoch Entropy Pool has minimal accumulated entropy. This is a known bootstrap limitation that resolves after Epoch 1. The initial pool value is set using a trustless future blockhash, not a founder-chosen value.'

Status: RESOLVED, Trustless initialization via future blockhash, reduced weight during Epoch 0.

AV-19 [MEDIUM→DOCUMENTED]: VDF Computation DoS via Beacon Block Stuffing

Attack: The Autonomous Beacon VDF is seeded by the previous beacon output and the current block hash. A block proposer on the beacon chain can influence the VDF input by choosing which transactions to include. If the VDF delay is too short, the proposer can grind multiple block options before the VDF completes.

Mitigation Documented in v3.9.3: (1) VDF parameters documented: minimum delay is 30 seconds (5x the beacon chain block time of 6 seconds). This ensures a block proposer cannot grind VDF inputs faster than the VDF computation completes. (2) The VDF seed includes the PREVIOUS VDF output, making it a recursive chain that cannot be influenced by a single block proposer, each output depends on all prior outputs. (3) The VDF delay parameter is configurable via on-chain governance and can be increased if grinding attempts are detected. (4) The VDF output contributes only 5% weight, even if the seed is partially influenced, the impact on the final seed is negligible.

Status: DOCUMENTED, VDF delay set to 30s (5x block time), recursive seeding prevents single-proposer influence.

AV-20 [LOW→RESOLVED]: Fee Distribution Dust Accumulation

Attack: Integer division in fee distribution truncates wei-level amounts. Over millions of events, dust accumulates in the contract with no owner. The v3.9.1 fix said 'dust remainder routed to gas pool' but the code did not actually implement this.

Fix Applied in v3.9.3: After the fee distribution loop, the contract now sends the remaining dust to the gas pool: gasPool += keeperPool - totalDistributed. This ensures no wei is permanently trapped. The variable totalDistributed accumulates each share during the loop, and the difference is sent to gasPool in a single operation after the loop completes.

Status: RESOLVED, Dust remainder routed to gas pool after distribution loop.

AV-21 [MEDIUM→RESOLVED]: No Protocol-Level Circuit Breaker / Emergency Pause

Attack: A zero-day vulnerability in KeeperCoordinator.sol could be exploited across all chains simultaneously. The protocol has no way to halt all fulfillments globally. The 'no admin key on fulfill()' design means there is no emergency stop. Individual keepers can stop signing, but only if they know about the attack.

Fix Applied in v3.9.3: (1) A protocol-level pause() function is added, callable only by a 5-of-7 multi-sig of genesis keepers (Phase 0/2) or by on-chain governance (Phase 4). (2) When paused, fulfill() reverts with 'Protocol paused, under investigation.' (3) requestRandomness() still works, requests queue up and are fulfilled when unpaused. (4) Pause is time-limited to 24 hours and auto-expires. (5) This is NOT an admin key on fulfill(), it is an emergency circuit breaker requiring 5-of-7 consensus, fundamentally different from single-party admin control. (6) The pause multi-sig signers are publicly disclosed and rotate with each phase. (7) Unpause requires the same 5-of-7 consensus.

Status: RESOLVED, 5-of-7 emergency circuit breaker with 24-hour auto-expiry added.

AV-22 [MEDIUM→DOCUMENTED]: Cross-Chain BLS Verification Gap on Non-EVM Chains

Attack: BLS aggregate verification uses BN254 pairing on EVM (EIP-197 precompile). Solana, Cardano, TON, and Sui do not have native BLS12-381 precompiles. If on-chain BLS verification is too expensive or not implemented, keepers might skip verification or do it off-chain, weakening the security model.

Mitigation Documented in v3.9.3: Per-chain BLS verification approach documented: (1) EVM chains: BN254 precompile (EIP-197), ~45,000 gas, proven, production-ready. (2) Solana: BLS12-381 verification in Rust via solana-bls library, estimated 200K-400K compute units, feasible within Solana's 1.4M CU limit. (3) Cardano: Off-chain BLS verification with on-chain hash commitment, Plutus V3 cannot perform pairing operations. The keeper submits the BLS proof hash on-chain; full verification is done off-chain by the keeper client. Other keepers can challenge via fraud proof. (4) TON: Off-chain BLS verification with on-chain hash commitment, Tact does not have BLS libraries. Same approach as Cardano. (5) Sui: BLS verification in Move via sui::bls12381 module (available in Sui Move stdlib), native support. (6) Disclosure: 'Chains without native BLS precompiles (Cardano, TON) rely on off-chain BLS verification with on-chain proof commitment and fraud-proof challenge window. This is a known limitation that slightly reduces on-chain verifiability on those chains but is mitigated by the Layer 3 fraud-proof mechanism.'

Status: DOCUMENTED, Per-chain BLS verification approaches documented, non-EVM limitations disclosed.

AV-23 [LOW→DOCUMENTED]: TON jUSDT vs USDC Settlement Discrepancy

Attack: Not an attack but a settlement risk. On TON, fees are settled in jUSDT (Tether on TON) presented as 'USDC equivalent.' jUSDT is NOT USDC, it carries Tether counterparty risk, not Circle counterparty risk. If Tether freezes or depegs jUSDT, keeper earnings on TON lose value.

Mitigation Documented in v3.9.3: Documented: 'TON settlement uses jUSDT (Tether on TON) as there is no native USDC on TON. Keepers on TON carry Tether counterparty risk, not Circle counterparty risk. This will be replaced with native USDC if Circle deploys on TON. The wallet UI clearly labels TON earnings as jUSDT, not USDC, to prevent confusion.'

Status: DOCUMENTED, jUSDT vs USDC distinction disclosed.

AV-24 [MEDIUM→DOCUMENTED]: Commit-Reveal Internal Aggregation Still Uses XOR

Attack: The main aggregation formula was upgraded from XOR to keccak256 hash-chain (C-01 fix). But Source 4 (Participant Commit-Reveal) still uses participantEntropy = commitRevealXOR, raw XOR internally. Two participants with identical reveals cancel to zero. A participant who can observe other reveals before the deadline (e.g., a late revealer, or one running multiple entries) can choose their own reveal value to bias the XOR output. Because Source 4 carries 10% weight in the final hash-chain, this is not enough to control the overall seed, but in raffles or selections with a small number of entrants, a 10% bias on the seed can meaningfully shift the attacker's own win probability, this is a real, exploitable edge for a participant with reveal-timing visibility, not a theoretical one.

Recommended Fix (Not Yet Confirmed in Shipped Code): Internal commit-reveal aggregation should change from XOR to hash-chain: participantEntropy = keccak256(abi.encode(reveal_1, reveal_2, ..., reveal_n)). This would preserve all participant entropy, prevent cancellation, and eliminate last-revealer bias (the last revealer cannot choose a value that produces a desired keccak256 output because keccak256 is not invertible). A reveal deadline should be enforced: after the deadline, late reveals are excluded and replaced with keccak256(committedHash). This whitepaper documents the correct fix here; it should not be read as confirmation that this fix is live in deployed contracts until verified against the audited, deployed bytecode.

Status: DOCUMENTED, Correct fix (hash-chain + reveal deadline) is specified above; implementation against deployed contract bytecode has not been independently confirmed. Treat as open until verified.

Round 2 Adversarial Audit Summary

12 additional attack vectors identified and addressed in v3.9.3. Critical finding AV-16 (NPM supply chain) resolved via Docker-only distribution with hash verification and Sigstore provenance. High findings AV-13 (light node poisoning) and AV-14 (gossip eclipse) resolved via advisory-only light node entropy and deterministic full-mesh peer selection at genesis. Medium findings AV-17 through AV-22 resolved or documented with mitigations. Low findings AV-20, AV-23 addressed with code fixes and disclosures.

Combined Audit Status (Round 1 + Round 2): 24 attack vectors analyzed across two adversarial audit rounds. 18 resolved with code fixes, 6 documented with mitigations. 0 unresolved critical or high findings remain. The protocol's security model is now backed by: (1) 4-layer entropy verification architecture, (2) full-mesh gossip at genesis with deterministic peer selection, (3) Docker-only software distribution with hash verification, (4) dual-confirmation mobile remote actions with timelocks, (5) 5-of-7 emergency circuit breaker, (6) hash-chain aggregation throughout (no XOR anywhere), (7) trustless epoch pool initialization, (8) per-chain BLS verification documentation, (9) treasury governance disclosure, and (10) external security audit requirement.

29.9 Adversarial White Hat Audit: Round 3 (v3.9.4)

Round 3 focused on operational security, economic exploits, cryptographic edge cases, and issues hidden in plain sight in the runbook and code examples. 10 additional attack vectors identified and mitigated.

AV-25 [HIGH→RESOLVED]: Private Key Exposure in CLI Commands

Attack: The node operator runbook contains 12+ instances of --private-key 0xYourPrivateKey passed as a CLI argument. On Linux/macOS, CLI arguments are visible to any process via ps aux, /proc/<pid>/cmdline, and shell history. An attacker on a shared VPS or compromised machine can read the keeper's private key in plaintext.

Fix Applied in v3.9.4: (1) All --private-key CLI arguments replaced with --keystore ./keys/keystore.json --password-file ./keys/.password (encrypted keystore file). (2) CLI refuses to accept plaintext private keys as arguments, requires file-based input only. (3) Documented warning: 'Never pass private keys as CLI arguments. Use --keystore or set KEEPER_PRIVATE_KEY in .env (chmod 600). On shared systems, use GPG-encrypted keystore files.' (4) Shell history clearing recommended after key operations. (5) .env file must be chmod 600 and never committed to version control.

Status: RESOLVED, All CLI commands updated to use encrypted keystore files. Plaintext key arguments rejected.

AV-26 [HIGH→RESOLVED]: Grafana Default Credentials in Docker Compose

- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-CHANGE_ME_BEFORE_FIRST_RUN} # AV-26: never use default

Fix Applied in v3.9.4: (1) Default password replaced with mandatory setup step: 'Generate a random password: openssl rand -base64 24 and set it in docker-compose.yml before first run.' (2) The (admin / YOUR_GENERATED_PASSWORD) comment removed from the runbook. (3) Grafana port bound to 127.0.0.1 only: 127.0.0.1:3001:3000 in docker-compose.yml. (4) Documented warning: 'Never expose port 3001 to the public internet. Bind to localhost only.' (5) Health check warns if Grafana is running with default credentials.

Status: RESOLVED, Default credentials removed, localhost binding enforced, mandatory password setup documented.

AV-27 [MEDIUM→RESOLVED]: No Rate Limiting on requestRandomness, Request Flood DoS

Attack: Anyone can call requestRandomness() with no rate limiting, no per-address cap, and potentially 0 fee. An attacker deploys a contract that calls requestRandomness() 10,000 times per block. Keepers waste compute, RPC calls, and gossip bandwidth fulfilling bogus events while real clients experience latency.

Fix Applied in v3.9.4: (1) Minimum fee enforcement: require(msg.value >= MIN_FEE, 'Fee below minimum') where MIN_FEE is set per chain (e.g., $0.05 in native asset or USDC). (2) Per-address rate limiting: mapping(address => uint256) public lastRequestBlock; require(block.number >= lastRequestBlock[msg.sender] + MIN_BLOCKS_BETWEEN_REQUESTS, 'Rate limited'), 1 request per 10 blocks per address. (3) ERC-20 approve + transferFrom for USDC payments so fee is enforced in the token. (4) Documented: 'The minimum fee serves as spam protection. Requests below the minimum are reverted. Per-address rate limiting prevents a single contract from flooding the network.'

Status: RESOLVED, Minimum fee enforcement + per-address rate limiting added.

AV-28 [MEDIUM→DOCUMENTED]: Stake-Weighted Fee Distribution Creates Centralization Pressure

Attack: Fee distribution is proportional to stake. A wealthy entity stakes 10x the minimum, earns 10x fees per event, restakes earnings, and grows further, a positive feedback loop that centralizes fee earnings toward large stakers and drives small operators out over time.

Mitigation Documented in v3.9.4: (1) Hybrid fee model documented: 50% proportional to stake, 50% split equally among all signers. This rewards higher stake without making it dominant. (2) Maximum fee share capped at 2x the equal-split baseline, a large staker cannot earn more than 2x what a minimum staker earns per event. (3) Monitoring: alert if any single keeper's stake exceeds 10% of total network stake. (4) Documented: 'Fee distribution is stake-weighted with a 2x cap to reward higher commitment without enabling centralization. The hybrid model (50% proportional, 50% equal) ensures small operators remain economically viable.'

Status: DOCUMENTED, Hybrid fee model with 2x cap documented to prevent stake centralization.

AV-29 [LOW→DOCUMENTED]: Cross-Chain Request Correlation

Attack: A client submits the same userSeed on multiple chains. Off-chain entropy sources (DRAND, NIST, Bitcoin, ANU, Tor) may be identical if both requests are fulfilled in the same time window, reducing effective entropy from 15 sources to 6 (on-chain sources only).

Analysis: With the hash-chain formula and chainId in message M, final seeds WILL differ between chains even with identical off-chain entropy. The chainId in M (fixed in v3.9) prevents cross-chain seed collision. The reduced entropy from shared off-chain sources is a minor information leak, not a manipulation vector, the attacker cannot control any of the 6 on-chain sources.

Status: DOCUMENTED, Cross-chain correlation is expected behavior. chainId in M guarantees unique outputs. No vulnerability.

AV-30 [LOW→RESOLVED]: BLS Rogue Key Attack

Attack: BLS aggregate signatures are vulnerable to rogue key attacks if keeper public keys are not proof-of-possession verified. An attacker registers a public key PK_attacker = PK_honest - PK_mine and can forge aggregate signatures without the honest keeper's participation.

Fix Applied in v3.9.4: During registerKeeper(), the keeper must submit a BLS proof-of-possession (PoP): a signature over keccak256('RandProof keeper registration', chainId, keeperAddress, blsPubKey). The contract verifies this PoP before accepting the public key. This prevents rogue key attacks because the attacker cannot produce a PoP for a public key whose private key they don't control.

Status: RESOLVED, BLS proof-of-possession required during keeper registration.

AV-31 [MEDIUM→RESOLVED]: Unbonding Period vs Challenge Window Mismatch

Attack: The fraud-proof challenge window is 10 blocks (~20 seconds) but the unbonding period is 7 days. A keeper who commits fraud can wait 20 seconds for the challenge window to pass, then unstake and withdraw in 7 days. If fraud is discovered after 20 seconds, the keeper's stake is already withdrawable.

Fix Applied in v3.9.4: (1) Fraud-proof challenge window extended from 10 blocks to 24 hours (~43,200 blocks on Base). During this window, fees are held in escrow, not distributed to keepers until the window expires. (2) If any keeper unstakes, their unbonding period does not begin until all events they signed have passed their 24-hour challenge windows. (3) If a fraud proof is submitted and verified during the window: fees refunded to requester, dishonest keeper slashed 100%, event re-fulfilled. (4) After 24 hours with no fraud proof: fees released to keepers, fulfillment is final. (5) Documented: 'The 24-hour challenge window ensures sufficient time for fraud discovery. Fees are escrowed during this period. Unbonding cannot begin until all signed events have cleared their challenge windows.'

Status: RESOLVED, Challenge window extended to 24h, fees escrowed, unbonding gated by challenge window clearance.

AV-32 [LOW→DOCUMENTED]: BLS Committee Size Fixed at 12: No Scaling Mechanism

Attack: BLS_COMMITTEE_SIZE=12 with t=3 is fixed. At Phase 4 (1,000+ nodes), only 12 keepers are in the signing committee. An attacker needs to control only 3 of 12 committee members (not 3 of 1,000) to forge an aggregate signature.

Mitigation Documented in v3.9.4: (1) Committee scaling formula documented: at Phase 2+, BLS_COMMITTEE_SIZE scales with network size: n = min(25, floor(sqrt(totalKeepers * 3))). At 1,000 nodes, n = ~55, t = ~18. (2) At Phase 4, signing committee is randomly selected from all registered keepers per event, with committee size n=25 and threshold t=9. (3) Committee selection is deterministic based on blockhash, predictable but not controllable. (4) An attacker must control 9 of 25 randomly selected keepers, much harder than 3 of 12. (5) Documented: 'The signing committee scales with network growth. At 1,000 nodes, the attacker needs 9 of 25 randomly selected keepers, not 3 of 12.'

Status: DOCUMENTED, Committee scaling formula documented. n and t grow with network size.

AV-33 [MEDIUM→DOCUMENTED]: FeeVault Centralization, Single Contract Holds All Protocol Revenue

Attack: FeeVault.sol holds all USDC and native asset balances for pending payouts on each chain. If FeeVault has a vulnerability, an attacker drains all accumulated fees on that chain.

Mitigation Documented in v3.9.4: (1) FeeVault access controls documented: 'FeeVault has no admin functions. The only functions are: creditKeeper(address, uint256) callable only by KeeperCoordinator, and withdraw() callable by any address with a positive balance. No single party can move funds that aren't theirs.' (2) FeeVault is a thin escrow, it cannot be paused, upgraded, or drained by any party. (3) All funds are either pending keeper withdrawals (pull-payment) or pending treasury transfers (timelocked). (4) Maximum balance cap: if accumulated balance exceeds 10x the average daily fee volume, automatic distribution is triggered. (5) FeeVault is immutable, no proxy, no upgrade pattern, no admin key.

Status: DOCUMENTED, FeeVault is a thin immutable escrow with no admin functions. Access controls and balance cap documented.

AV-34 [LOW→DOCUMENTED]: No Slashing Enforcement During Genesis

Attack: During genesis (12 founder-controlled nodes), slashing enforcement is at the operator's discretion since the same party controls all nodes. A genesis node going offline might not be slashed if the operator chooses not to enforce it.

Mitigation Documented in v3.9.4: Documented: 'During Phase 0 (Genesis), slashing enforcement is at the discretion of the protocol operator since all nodes are founder-controlled. Automatic slashing enforcement begins at Phase 2 when nodes are permissionless and operator-independent. This is a known limitation of the federated genesis phase and is disclosed alongside the Phase 0 trust model disclosure in Section 24.1.'

Status: DOCUMENTED, Genesis slashing discretion disclosed. Automatic enforcement at Phase 2.

Round 3 Adversarial Audit Summary

10 additional attack vectors identified and addressed in v3.9.4. High findings AV-25 (private key exposure) and AV-26 (Grafana defaults) resolved via runbook fixes and mandatory security steps. Medium findings AV-27 (request flood), AV-28 (fee centralization), AV-31 (challenge window), AV-33 (FeeVault) resolved or documented with mitigations. Low findings AV-29, AV-30, AV-32, AV-34 documented or resolved with code fixes.

Combined Audit Status (Round 1 + Round 2 + Round 3): 34 attack vectors analyzed across three adversarial audit rounds. 0 CRITICAL unresolved. 0 HIGH unresolved. 24 resolved with code fixes, 10 documented with mitigations. The protocol's security model is now backed by 10 layers of defense: (1) 4-layer entropy verification, (2) full-mesh gossip at genesis, (3) Docker-only distribution with hash verification, (4) dual-confirmation mobile actions, (5) 5-of-7 emergency circuit breaker, (6) hash-chain aggregation throughout, (7) trustless epoch pool initialization, (8) BLS proof-of-possession, (9) 24-hour fraud-proof challenge window with fee escrow, (10) minimum fee + rate limiting spam protection. No protocol in the Web3 randomness space has undergone this depth of adversarial security review before mainnet deployment.

29.10 Adversarial White Hat Audit: Round 4: Threat-Actor Scenarios (v3.9.5)

Round 4 simulates three specific threat actors: a DDoS botnet operator (10,000-node botnet), a Chainlink competitor ($100K+ treasury for infiltration), and a Web3 hacker group (Lazarus/Nomad-style, $10M+ attack budget). 13 attack vectors identified across these scenarios.

Scenario A, DDoS Botnet Operator (10,000-node botnet)

AV-35 [HIGH→RESOLVED]: Keeper API DDoS (Port 3000)

Attack: The keeper node exposes a health API on port 3000. The runbook says 'ufw allow 3000/tcp' which allows public access. A botnet floods it with 100K requests/second, crashing the Node.js health endpoint and causing the keeper to miss fulfillment windows.

Fix Applied in v3.9.5: (1) Port 3000 binds to 127.0.0.1 only, docker-compose updated to '127.0.0.1:3000:3000'. (2) UFW rule changed to 'ufw allow from 127.0.0.1 to any port 3000'. (3) Health endpoint rate limited to 10 req/sec. (4) Documented: 'Port 3000 is localhost-only. Never expose to the public internet.'

Status: RESOLVED, Localhost binding + rate limiting on health endpoint.

AV-36 [HIGH→RESOLVED]: P2P Gossip Port DDoS (Port 4001)

Attack: Port 4001 (P2P gossip) must be publicly accessible. A botnet floods it with 10K TCP SYN/second per target node, exhausting file descriptors and preventing legitimate peer connections.

Fix Applied in v3.9.5: (1) libp2p connection limits: max 50 inbound, max 100 total connections. (2) Per-IP limit: max 3 connections from the same IP. (3) libp2p resource manager caps bandwidth per peer. (4) UFW: 'ufw limit 4001/tcp' prevents brute-force connection flooding. (5) Documented: 'Port 4001 must be open but rate-limited. Use ufw limit for basic protection. For home routers, consider Cloudflare Tunnel or WireGuard overlay for gossip traffic.'

Status: RESOLVED, Connection limits, per-IP caps, UFW rate limiting documented.

AV-37 [MEDIUM→RESOLVED]: RPC Endpoint Exhaustion

Attack: Instead of attacking keeper nodes, the botnet floods free public RPC endpoints (e.g., wss://api.mainnet-beta.solana.com) that some keepers depend on. Keepers using free RPCs get disconnected and can't detect events.

Fix Applied in v3.9.5: (1) Documented: 'Free public RPC endpoints are for testing only. Production keepers MUST use dedicated RPC providers (Alchemy, Infura, QuickNode, Helius).' (2) Multi-RPC fallback: keeper config supports 2+ endpoints per chain with automatic failover. (3) Health check: if RPC latency exceeds 5 seconds, keeper switches to backup RPC. (4) Free RPC endpoints removed from production .env examples, replaced with dedicated provider placeholders.

Status: RESOLVED, Dedicated RPC required, multi-endpoint failover documented.

AV-38 [MEDIUM→RESOLVED]: Entropy Source API DDoS

Attack: The botnet DDoSes external entropy source APIs, NIST beacon, ANU QRNG, which are small government/academic servers with limited capacity. If sources go stale, the entropy pool weakens.

Fix Applied in v3.9.5: (1) Multi-endpoint fallback: NIST has mirrors. ANU QRNG has no independent fallback provider as of this writing, its prior listed fallback, HotBits, retired its original radioactive-decay hardware at the end of 2022 and the service now running under that name is an uncertified CPU-level generator, which RandProof does not treat as an equivalent or acceptable substitute source. If ANU QRNG is unavailable, its weight is redistributed per (2) below rather than routed to a degraded substitute. (2) Staleness windows enforced (NIST 60s, ANU 30s, Tor 65min), stale sources are excluded. (3) Weight redistribution: if a source is stale, its weight is redistributed proportionally to remaining sources. (4) Sources 13-15 (protocol-native) are immune to external DDoS, they always remain available. (5) Documented: 'External entropy sources have fallback endpoints where genuinely independent ones exist. Stale sources are automatically excluded with proportional weight redistribution. Protocol-native sources (13-15) are DDoS-immune.'

Status: RESOLVED, Fallback endpoints, staleness exclusion, weight redistribution, protocol-native immunity documented.

Scenario B, Chainlink Competitor Attack ($100K+ treasury)

AV-39 [MEDIUM→DOCUMENTED]: Competitor-Funded Sybil Infiltration

Attack: A well-funded competitor (e.g., Chainlink Labs) uses $100K to register 500 keeper nodes at $20-60 each. They participate honestly but accumulate 50% of the network. At Phase 4 with committee n=25, they statistically control ~12-13 committee members, enough to block fulfillments or selectively censor events. The attacker follows all rules, the protocol cannot distinguish competitor nodes from community nodes.

Mitigation Documented in v3.9.5: (1) Stake concentration cap: no single entity can control more than 15% of total network stake. Enforced via on-chain stake aggregation, if an address or linked cluster exceeds 15%, new registrations are rejected. (2) IP/ASN diversity monitoring: alert if >20% of nodes share the same ASN. (3) KYC-optional path: keepers can optionally verify identity (via Gitcoin Passport or similar) to receive a 'verified independent operator' badge. Clients can choose to only use events signed by verified operators. (4) Documented: 'The protocol enforces a 15% stake concentration cap. No single entity can control more than 15% of total network stake, preventing well-funded competitors from silently acquiring majority node share.'

Status: DOCUMENTED, 15% stake concentration cap, ASN diversity monitoring, verified operator badges.

AV-40 [LOW→DOCUMENTED]: FUD Campaign, Trust Attack

Attack: A competitor launches a PR campaign highlighting that Competitor VRF has been live since 2020 while RandProof has zero production history. They fund 'security researchers' to find and publicly disclose minor issues. They sponsor content comparing RandProof to failed oracle projects. This is a trust attack, not a technical one.

Mitigation Documented in v3.9.5: (1) The 4-round adversarial audit (47+ attack vectors) is the strongest counter-narrative, no competitor can claim this depth of pre-mainnet review. (2) External audit report published publicly. (3) Bug bounty program (Immunefi or similar) with $100K+ rewards from day one. (4) Start with BIT5050 as real production client, demonstrate months of successful operation before expanding. (5) Documented: 'RandProof undergoes the most comprehensive pre-mainnet security review of any randomness protocol. 47+ attack vectors analyzed across 4 adversarial audit rounds plus external firm review. Bug bounty program live from day one.'

Status: DOCUMENTED, Audit depth, bug bounty, and production track record as FUD defense.

AV-41 [MEDIUM→DOCUMENTED]: DRAND/LoE Influence Attack

Attack: Chainlink is a member of the League of Entropy (LoE). As an LoE member, they could push for drand changes that subtly affect RandProof's Sources 1 and 12 (25% combined weight), e.g., changing drand's round interval or signature scheme to break on-chain verification.

Mitigation Documented in v3.9.5: (1) RandProof should join the LoE as a member to have visibility into governance changes. (2) Documented drand contingency plan: 'If drand changes its parameters, RandProof keepers must update within 24 hours. If drand becomes unreliable, Sources 1 and 12 weight is redistributed to the 13 remaining sources via 5-of-7 multi-sig governance action.' (3) The hash-chain formula means a drand parameter change doesn't break aggregation, it changes how drandEntropy is computed. (4) LoE trust root disclosure (E-01) already documents the shared trust root risk.

Status: DOCUMENTED, LoE membership, drand contingency plan, weight redistribution documented.

Scenario C, Web3 Hacker Group (Lazarus/Nomad-style, $10M+ budget)

AV-42 [HIGH→RESOLVED]: Discord/Telegram Social Engineering

Attack: The hacker group creates a fake 'RandProof Support' Discord server with a typosquatted invite (discord.gg/randpr00f). They post fake 'critical update' messages linking to a malicious docker image (randproof/randproofkeeper:latset, typosquat of latest). Node operators who pull this image run compromised keeper software, all keys exfiltrated.

Fix Applied in v3.9.5: (1) All typosquat Discord/Telegram handles and domain names registered. (2) Documented: 'The ONLY official channels are discord.gg/randproof (verify on randproof.network), t.me/randproof, and github.com/randproof-network.' (3) Docker image verification: cosign verify --key cosign.pub randproof/randproofkeeper:latest, automatic in CLI. (4) Discord bot cross-verification: official Discord bot posts signed messages that the CLI can verify. (5) Documented warning in runbook: 'Never trust update links from unofficial sources. Always verify Docker image signatures.'

Status: RESOLVED, Typosquat registration, Cosign verification, official channel verification documented.

AV-43 [CRITICAL→RESOLVED]: Docker Image Registry Compromise

Attack: The hacker group compromises Docker Hub credentials for the 'randproof' organization (phishing, credential stuffing, or insider threat). They push a malicious randproof/randproofkeeper:latest image with a backdoor that exfiltrates BLS keys. Every node operator who runs 'docker pull' gets compromised. This is the single most destructive attack, one compromised image update gives the attacker every node's keys.

Fix Applied in v3.9.5: (1) Docker Hub account secured with hardware security key (YubiKey) 2FA, not SMS. (2) Docker images signed with Cosign (Sigstore): cosign verify --key cosign.pub randproof/randproofkeeper:latest. The keeper CLI verifies the signature automatically before running, if verification fails, the keeper refuses to start. (3) Multi-stage build with reproducible builds: anyone can rebuild from source and verify digest matches. (4) GitHub Actions CI/CD with OIDC token authentication, no long-lived Docker Hub credentials. (5) Image pinning in production: randproof/randproofkeeper@sha256:abc123... not :latest. (6) Documented: 'Always verify Docker image signature before running. The CLI does this automatically. If signature verification fails, the keeper refuses to start.'

Status: RESOLVED, Cosign image signing, YubiKey 2FA, OIDC CI/CD, automatic signature verification, image pinning.

AV-44 [HIGH→RESOLVED]: GitHub Repository Maintainer Compromise

Attack: The hacker group compromises a GitHub maintainer's credentials (phishing, SIM swap, stolen session token). They push a malicious commit with a backdoor in the BLS signing module. Even though releases are GPG-signed, a compromised maintainer key signs the malicious commit. Node operators who build from source get compromised.

Fix Applied in v3.9.5: (1) All maintainers use hardware security keys (YubiKey) for GitHub 2FA. (2) Branch protection: require 2-of-3 maintainer approvals for all commits to main, no single-maintainer push. (3) GPG signing keys on hardware tokens (YubiKey/GnuK), not software. (4) Reproducible builds: Docker image is built from a specific commit hash, anyone can rebuild and verify digest. (5) Documented: 'All releases are GPG-signed by 2-of-3 maintainers. Verify with: git verify-commit HEAD. Never build from unsigned commits. Maintainer public keys published at randproof.network/maintainers.'

Status: RESOLVED, Hardware 2FA, 2-of-3 branch protection, hardware GPG keys, reproducible builds.

AV-45 [MEDIUM→DOCUMENTED]: Alchemy/Infura RPC Provider Compromise

Attack: The hacker group compromises an Alchemy or Infura employee (social engineering, bribery). They manipulate RPC responses to targeted keeper nodes, fake block data, fake PREVRANDAO values, fake block timestamps.

Mitigation Documented in v3.9.5: (1) On-chain entropy sources (PREVRANDAO, block.timestamp, Sources 13-15) are read directly by the smart contract, NOT submitted by keepers. A compromised RPC cannot manipulate these sources. (2) RPC is used only for event detection and off-chain entropy submission. (3) Multi-RPC redundancy: keepers use 2+ providers and cross-check block data. (4) For off-chain sources, multi-keeper attestation (Layer 2) requires 2 independent keepers to submit matching values, a single compromised RPC isn't enough. (5) Documented: 'On-chain entropy sources are read by the contract directly. A compromised RPC cannot manipulate them. RPC is used only for event detection and off-chain entropy submission with multi-keeper attestation.'

Status: DOCUMENTED, On-chain sources immune to RPC compromise. Multi-provider redundancy and multi-keeper attestation mitigate off-chain risk.

AV-46 [NO ISSUE]: withdraw() Reentrancy, Confirmed Safe

Attack: A malicious keeper contract with a reentrant receive() function attempts to re-enter cancelRequest() or fulfill() during the withdraw() call.

Analysis: withdraw() follows Checks-Effects-Interactions pattern (pendingWithdrawals[msg.sender] = 0 before call). Reentering withdraw() gets 0. Reentering cancelRequest() fails because msg.sender != requesters[eventId]. Reentering fulfill() requires a valid BLS signature. No vulnerability found. Documented for external auditor reference.

Status: NO ISSUE, CEI pattern correct, access controls prevent cross-function reentrancy.

AV-47 [HIGH→RESOLVED]: Entropy Source DNS Hijacking

Attack: The hacker group compromises a DNS registrar or BGP route for beacon.nist.gov, qrng.anu.edu.au, or api.drand.sh. They redirect keeper HTTP requests to their server, serving fake entropy values. Keepers fetch what they think is the real NIST/ANU/drand value but it's attacker-controlled.

Fix Applied in v3.9.5: (1) DNSSEC validation: keepers use DNSSEC-resolving DNS servers and validate DNSSEC signatures for entropy source domains. (2) TLS certificate pinning: keeper client pins TLS certificates for all entropy source APIs, same as mobile app does for RandProof endpoints. (3) Multi-source cross-validation: DRAND values verified by BLS signature (on-chain). NIST values verified by ECDSA signature. If fetched value fails signature verification, keeper rejects it and uses alternative source. (4) Documented: 'All entropy source HTTP connections use TLS certificate pinning. DRAND and NIST values are cryptographically signed, a DNS hijack cannot forge the signature. If signature verification fails, the keeper rejects the value and falls back to alternative sources.'

Status: RESOLVED, TLS pinning, DNSSEC validation, cryptographic signature verification on all entropy source connections.

AV-48 [HIGH→DOCUMENTED]: Selective Non-Fulfillment by a Self-Interested Genesis Keeper

Attack: AV-09 addresses a keeper choosing who signs. It does not address a keeper choosing whether to submit. A keeper who is also a participant in (or has a financial interest in) the outcome of a specific PoFR event can privately compute the resulting seed and outcome from observable entropy inputs before calling fulfill(), and then simply withhold its signature if the outcome is unfavorable to it. Because the rotating committee only requires t=3 of n signers, a keeper holding one of the 3 assigned slots can stall a single event toward the FULFILLMENT_TIMEOUT (256 blocks), after which the requester receives a refund via cancelRequest() rather than a draw. This is not a manipulation of the random value, no entropy source is biased, but a manipulation of which outcomes get published, achieved by selectively refusing service. This is most exploitable during Phase 0–1, when the founder-controlled keeper set is both small (n=12, t=3) and may itself participate in or have an economic stake in client events (e.g., BIT5050 as genesis client).

Mitigation (Planned, Not Yet Code): Recommended fix is to require keepers to submit a commitment to their partial signature (e.g., a hash of σ_i) at the time they detect the event, before any keeper has had the opportunity to compute the final seed. A keeper who commits and then fails to reveal within the fulfillment window forfeits stake (slashing), separating "I could not see the outcome in advance" from "I saw it and refused." Until this commit-before-compute mechanism ships in code, RandProof discloses this as an open risk rather than a resolved one: the FULFILLMENT_TIMEOUT and cancelRequest() (Section 19.1) limit the damage to a delayed/refunded event rather than a stolen one, but they do not prevent a self-interested keeper from selectively stalling unfavorable outcomes during Phases 0–1.

Status: DOCUMENTED, Liveness/refund safeguard exists (Section 19.1); commit-before-compute fix to fully close the selective-withholding gap is planned, not yet implemented. Clients running high-value or adversarial-participant use cases (e.g., liquidation ordering, IPO tiebreaks) during Phases 0–1 should treat this as a live, disclosed limitation.

AV-49 [LOW→RESOLVED]: Treasury Bridge Dependency on Non-USDC-Native Chains

Attack: Section 32.10.1 (prior revision) described bridged USDC settlement via Wormhole for BNB Chain, Avalanche, Moonbeam, TON, Sui, and a Wormhole-bridged swap path for Cardano and Polkadot treasury consolidation. Bridges are the single most exploited category of infrastructure in Web3; routing 20% protocol revenue from six or more chains through a third-party bridge concentrates value-at-risk in a system RandProof does not control, independent of any RandProof contract vulnerability. The prior 24-hour timelock (AV-15) reduces RandProof's own response time to a detected exploit but does not protect funds already in transit inside the bridge's contracts.

Fix (Adopted): RandProof's settlement policy is revised: on any chain where native Circle USDC is available via CCTP V2 (Ethereum, Base, OP, ARB, Solana, HyperEVM), fees and treasury settlement use native USDC with no bridge involved. On chains where native USDC is not available (Cardano, TON, and any future chain without a CCTP V2 deployment), RandProof settles, holds, and accounts for protocol revenue exclusively in that chain's native asset (ADA, TON, etc.) rather than bridging to a USDC representation. This removes Wormhole, or any other third-party bridge, from the treasury settlement path entirely. The tradeoff, disclosed openly: RandProof's treasury holds a basket of native assets rather than a single bridge-free USDC balance, and is therefore exposed to native-asset price volatility on those chains until and unless a given chain adds native (non-bridged) USDC support, at which point that chain can transition to USDC settlement.

Status: RESOLVED, Bridge dependency eliminated from treasury settlement by policy; native-asset volatility exposure is the accepted, disclosed tradeoff. See Section 32.10 for the updated per-chain settlement table.

AV-50 [HIGH→DOCUMENTED]: Single-Founder Key Custody During Genesis

Attack: Section 22.2 describes the protocol treasury as a Gnosis Safe multisig with a 3-of-5 threshold during Genesis and Phase 2. As of this writing, RandProof Network is operated by a single founder, and no additional independent cosigners currently hold keys. AV-42 through AV-47 model social-engineering and infrastructure attacks against community members, repository access, and Docker distribution, but do not separately model the simplest version of this risk: a single human controlling effectively all founder-side credentials (repository admin, Docker publishing, and, at Genesis, treasury signing) is a single point of failure for coercion, compromise, accident, or unavailability, independent of any code-level control.

Disclosure (Current State, Honestly Stated): During Genesis, RandProof Network's treasury and infrastructure credentials are held by a single founder (Mauricio Artigas). The 3-of-5 multisig described in Section 22.2 is the Phase 2 target structure, not the current state; it has not yet been constituted with independent cosigners. Until additional cosigners are onboarded and disclosed at randproof.network/treasury, treasury funds, repository control, and node-distribution channels should be understood as single-key custody, with the operational and security exposure that implies. RandProof commits to disclosing the actual cosigner roster the moment it changes from this single-founder state, rather than allowing the Section 22.2 target structure to be read as already in effect.

Status: DOCUMENTED, Single-founder custody is the accurate current state and is disclosed as such. Transition to a genuine 3-of-5 multisig with independent, named cosigners is a precondition for the Phase 2 trust claims in Section 22.2, not a fact of the present.

AV-51 [MEDIUM→DOCUMENTED]: Static Native-Asset Fee Amounts Drift From Intended USD Price

Note on scope: this finding is about RandProof's own fee mechanism, not about price risk on holdings. Users who earn or settle in a native asset bear that asset's market risk by their own choice, and RandProof does not attempt to protect against that, that is normal, expected crypto market exposure, not a protocol vulnerability. The issue below is narrower: whether RandProof's own contracts charge the fee they were designed to charge.

Issue: Section 29.1's fee table specifies fixed native-asset amounts per chain (e.g., 0.2 TON, 0.5 ADA, 0.1 BNB) intended to approximate a target USD fee ($0.10-$0.25). Under the AV-49 policy, six chains (TON, Cardano, BNB, Avalanche, Moonbeam, Sui) now settle exclusively in native asset with no USDC reference. If these native amounts are hardcoded in the contract or client SDK rather than periodically repriced against a USD reference, normal price movement in the native asset causes the actual USD-equivalent fee charged to drift arbitrarily far from the intended amount over time, this is a mechanical consequence of fixed-quantity pricing in a floating-price asset, not an edge case. This affects RandProof's own revenue and fee-fairness guarantees (a fee that silently becomes 10x or 0.1x its intended USD value undermines the "no volume discounts, flat-rate, fair for all" claim in Section 29.1), independent of any volatility risk the user separately bears on their own holdings.

Recommended Fix (Not Yet Specified in Code): Native-asset fee amounts on non-USDC chains should be repriced on a defined schedule (e.g., via a price oracle read at fixed intervals, or a periodic parameter update) against the target USD fee, rather than fixed indefinitely at deployment-time native quantities. This is purely a fee-mechanism correctness question for RandProof's own contracts; it has no bearing on, and does not attempt to offer, any protection for a user's choice to hold the native asset they earn.

Status: DOCUMENTED, Fee-repricing mechanism not yet specified. Scope is limited to RandProof's own fee-charging correctness; user-held native-asset price risk is explicitly out of scope and not something RandProof undertakes to mitigate.

AV-52 [LOW→DOCUMENTED]: Light Node Dust Accumulation Re-Scoped to Six Additional Native-Asset Chains

Issue: AV-20 (Fee Distribution Dust Accumulation) was resolved against an architecture where several chains settled in USDC, which has negligible per-unit gas-to-claim friction. Under AV-49, six chains (TON, Cardano, BNB, Avalanche, Moonbeam, Sui) now settle exclusively in native assets. Mobile light node earnings (Section 24.3: $20-50/month from 2-5% fee shares) accrue in small native-asset amounts on these chains; a light node operator whose accrued balance is worth less than the gas cost to call withdraw() on that chain cannot economically claim it. This is a UX/systems issue for honest small operators (their own funds becoming practically unclaimable due to RandProof's own payout granularity), not a third-party attack, but it is a direct, foreseeable consequence of the AV-49 policy that AV-20's original resolution did not anticipate.

Recommended Fix (Not Yet Specified in Code): A minimum-accrual-before-payout threshold per chain, sized so that withdrawal value reliably exceeds withdrawal gas cost, or a batched/aggregated withdrawal mechanism shared across many light node operators on the same chain. Either approach is a payout-mechanism design question for RandProof's own contracts, distinct from any market-price question.

Status: DOCUMENTED, Re-flagged for the six chains newly affected by AV-49; not yet addressed with a per-chain minimum-payout threshold or batching mechanism.

AV-53 [MEDIUM during Genesis/Phase 1→LOW at Phase 4]: AV-01 Severity Re-Scoped, Genesis-Phase Keeper-Controlled Entropy Combines With AV-48

Issue: AV-01 (Keeper-Controlled Entropy Grinding, Sources 13-15) is rated [MEDIUM→LOW], a rating appropriate once Sources 13-15 (RandProofVRF, Autonomous Beacon, Epoch Entropy Pool) are decentralized at Phase 4 scale (1,000+ nodes, Section 26). Section 26's Phase 1 disclosure states these same three sources are "live from Genesis but only fully decentralized at higher node counts." During Genesis/Phase 1, the keeper set generating Sources 13-15 is the same 10-12 founder-controlled node set described in Section 24.1: meaning three of the fifteen entropy inputs are not independent of the signing keepers at this phase. This compounds AV-48 (selective non-fulfillment by a self-interested keeper): a Genesis-phase keeper holding a signing slot may also influence 3 of 15 entropy inputs feeding the very outcome it is deciding whether to publish, which is a stronger position than either finding describes in isolation.

Recommended Fix: Disclose AV-01's severity as phase-dependent explicitly (Genesis/Phase 1: MEDIUM, compounding with AV-48; Phase 4: LOW, as currently rated), rather than a single LOW rating that implicitly assumes Phase 4 conditions. The AV-48 commit-before-compute mitigation, once implemented, should be specified to cover Sources 13-15 generation as well as signature submission, so the same fix closes both the withholding gap and the Genesis-phase entropy-independence gap together.

Status: DOCUMENTED, AV-01's LOW rating holds at Phase 4 target conditions; Genesis/Phase 1 carries the higher, compounded severity described above until AV-48's fix is implemented and confirmed to cover Source 13-15 generation.

Round 6 Adversarial Audit Summary

3 findings from external white-hat re-review following the AV-49 policy change: AV-51 (static native-asset fee amounts drifting from intended USD price) and AV-52 (light node dust accumulation on the six chains newly settled in native assets) are both scoped explicitly to RandProof's own fee-charging and payout mechanisms, neither is about, nor attempts to address, the market-price risk a user accepts by choosing to hold a native asset they earn; that risk is the user's own to manage and is not a protocol vulnerability. AV-53 sharpens AV-01's severity rating to be phase-dependent, since the LOW rating assumes Phase 4 node-count decentralization of Sources 13-15 that does not hold during Genesis/Phase 1, where it compounds with AV-48. RandProof's security posture continues to distinguish third-party and systems risk, which is RandProof's responsibility to secure, from market risk on assets a user holds by choice, which is not.

Editorial note (v0.57): Subsection numbers 29.7 through 29.10 are intentionally unassigned. The Round 4-6 findings they once carried are documented within Sections 29.2 through 29.6 and summarized in Section 29.18; the numbering of Rounds 7 onward (29.11 and later) is retained unchanged for citation stability. Recorded here per AV-142 (Round 15) so the gap reads as deliberate rather than as a numbering defect.

29.11 Adversarial White Hat Audit: Round 7: Attack Vector Discovery

Round 7 simulates a sophisticated Web3 hacker group with a $50M+ budget conducting a fresh adversarial review focused on entropy manipulation, keeper network attacks, smart contract vulnerabilities, and infrastructure/supply chain attacks. 23 new attack vectors were identified that Rounds 1–6 did not surface.

AV-54 [HIGH]: Weight Redistribution Exploitation via Targeted Source Suppression

Attack: The protocol redistributes weight from stale entropy sources proportionally to remaining sources. An attacker can deliberately DDoS or compromise specific external entropy sources (NIST, ANU QRNG, Tor, small academic/government servers) to shift weight onto protocol-native Sources 13-15, which during Genesis are founder-controlled.

Root Cause: Weight redistribution (AV-38) is designed for graceful degradation but creates a gameable incentive. Taking sources offline shifts weight to remaining sources, including protocol-native sources that at Genesis are controlled by the federated keeper set.

Cost to Attack: $5,000-$50,000 (DDoS capacity against small servers).

Mitigation: (1) Cap weight redistribution at +2% per source. (2) Redistribute stale source weight ONLY to other EXTERNAL sources, never to protocol-native Sources 13-15. (3) Pause new PoFR events if >30% of external sources are stale within 1 hour.

AV-55 [MEDIUM]: VDF Hardware Acceleration Attack (Source 14: Autonomous Beacon)

Attack: VDF security assumes no attacker can compute faster than the delay period (30s). A wealthy attacker could build custom FPGA/ASIC hardware optimized for the VDF construction, computing the output 3-5x faster (6-10 seconds), giving them 20+ seconds of advance knowledge of the Autonomous Beacon output.

Root Cause: VDF sequentiality assumes equivalent hardware. Custom ASIC hardware can break this assumption for specific VDF constructions.

Cost to Attack: $2,000,000-$5,000,000.

Mitigation: (1) Use standardized Wesolowski VDF with minimal ASIC advantage. (2) Increase delay to 120s (20x block time). (3) Reject VDF proofs arriving in <50% of expected delay. (4) Rotate VDF parameters periodically.

AV-56 [MEDIUM]: Epoch Entropy Pool Cross-Epoch Poisoning

Attack: During low-volume periods (Genesis, 3am), an attacker who participates in the few events of an epoch can disproportionately influence the epoch pool value that carries forward to ALL future epochs. With ~100 events/day at Genesis, a 3am hour may have only 1-2 events, those 1-2 events determine 5% of entropy for the entire next epoch.

Root Cause: The epoch pool (Source 15) is recursive: epochPool_N = keccak256(epochPool_N-1, allEventSeeds_N-1, allKeeperCommits_N-1). Low event volume means few inputs determine the pool value.

Cost to Attack: $15-$60 (3 x minimum fee, refunded if cancelled).

Mitigation: (1) Require 20+ events before epoch pool uses full 5% weight. (2) Use rolling window (last 50 events) instead of fixed epochs. (3) Exclude cancelled requests from epoch pool. (4) Minimum epoch duration of 2 hours AND minimum 10 events.

AV-57 [LOW]: DRAND Round Selection Window Exploitation

Attack: DRAND produces a new round every 3 seconds. A request near a DRAND round boundary could legitimately use round R or R+1. A keeper can choose the more favorable round, grinding a one-round difference that changes the 20%-weight DRAND entropy input.

Root Cause: No deterministic round selection rule specified in the whitepaper.

Cost to Attack: $0 (requires keeper access).

Mitigation: Deterministic rule: ALWAYS use the latest DRAND round with round_time <= requestBlock.timestamp. Contract verifies this on-chain.

AV-58 [MEDIUM]: Multi-Chain Block Hash Correlation Amplification

Attack: E-03 flagged EVM correlation in Source 8. This finding shows hidden Ethereum correlation of up to 20%: Sources 2 (Chain-Native VRF, 10%), 6 (Ethereum RANDAO, 5%), and 8 (Multi-Chain Hashes, 5%) all share an Ethereum trust root when used on EVM chains. Base, OP, ARB sequencers are centralized, compromising 3 sequencers gives correlated control of 20% of entropy.

Root Cause: EVM L2s (Base, OP, ARB) share Ethereum settlement. Their block hashes are determined by centralized sequencers.

Cost to Attack: $10,000,000-$50,000,000 (compromise 3 L2 sequencer operators).

Mitigation: (1) Require 3+ non-EVM chains in multi-chain hash set. (2) Weight EVM L2 hashes at 0.5x, non-EVM at 1.0x. (3) Document hidden correlation: Sources 2, 6, and 8 share an Ethereum trust root on EVM chains; combined Ethereum-correlated weight is up to 20%.

AV-59 [HIGH]: BLS Aggregate Signature Malleability via Crafted Partial Contributions

Attack: BLS aggregate signatures verify against the aggregate public key, but individual contributions are not independently verifiable from the aggregate alone. A malicious signer could contribute a crafted partial signature that, when aggregated with honest signers' contributions, produces an aggregate valid for a DIFFERENT message than honest signers intended. The contract accepts the attacker's preferred entropy with a valid aggregate signature.

Root Cause: The fulfill() function verifies only the aggregate signature, not individual partial signatures against the message M.

Cost to Attack: $0 (requires 1 of 3 signing slots at Genesis).

Mitigation: Require each signer's partial signature submitted alongside the aggregate. Contract verifies the pairing for each individual signer. This eliminates the malleability attack.

AV-60 [MEDIUM]: Committee Selection Predictability at Phase 2+ (Blockhash Grinding)

Attack: Committee is selected by blockhash. An MEV searcher or validator who can influence block contents can predict the next block's committee and pre-attack selected keepers (DDoS, bribe) in the 2-12 second window before fulfillment.

Root Cause: blockhash-based committee selection is predictable 1 block in advance.

Cost to Attack: $50,000-$500,000 (Base validator stake + DDoS infrastructure).

Mitigation: Use blockhash(block.number - 2) for committee selection (1 block of unpredictability). Or use VRF-based selection.

AV-61 [MEDIUM]: Cross-Chain Keeper Schizophrenia Attack

Attack: A keeper registered on multiple chains can observe the same external entropy (DRAND, NIST, Bitcoin) for concurrent events on different chains. The keeper computes both outcomes and selectively fulfills the favorable one while delaying/cancelling the unfavorable one.

Root Cause: External entropy sources are time-based and shared across all chains. Same keeper set monitors multiple chains.

Cost to Attack: $0 (requires keeper access on 2+ chains).

Mitigation: (1) Require fulfillment within 30 seconds or face slashing. (2) Track keeper latency per chain, flag inconsistencies. (3) AV-48 commit-before-compute fix mitigates this.

AV-62 [LOW]: Micro-Node Stake Grinding for Committee Selection

Attack: At $20 minimum stake, an attacker registers 50 nodes ($1,000-3,000) to maximize committee selection probability. With 100 total nodes and n=25, expected attacker committee members = 12.5: above t=9 threshold.

Root Cause: Low minimum stake makes committee grinding cheap. 15% cap is per-address, bypassable with multiple addresses.

Cost to Attack: $1,000-$3,000.

Mitigation: (1) Entity-level clustering analysis for stake cap enforcement. (2) Increase committee n=50, t=18 at Phase 2. (3) Delayed reveal registration.

AV-63 [MEDIUM]: Emergency Pause Multisig Capture

Attack: Get 5 of 7 pause multisig signers controlled by attacker. Repeatedly pause (24h windows) to grief clients. Costs clients 24h downtime per cycle, drives them to Chainlink.

Root Cause: Pause multisig selected from keeper set, if by stake, attacker with higher stake gets selected.

Cost to Attack: $200-$420 (7 nodes x above-minimum stake).

Mitigation: (1) Rotate multisig deterministically (not by stake). (2) Require 7-of-9 instead of 5-of-7. (3) Cooldown period after pause/unpause cycle. (4) Community slashing vote for abusive signers.

AV-64 [LOW]: BLS Key Rotation Dual-Key Window Exploitation

Attack: During the 24-hour key rotation overlap, both old and new keys are active. An attacker who compromised the old key has 24 hours to use it.

Root Cause: 24-hour timelock creates a dual-key window.

Cost to Attack: $0 (requires prior key compromise).

Mitigation: (1) Reduce overlap to 1 hour. (2) Require co-signing with both old and new keys during transition. (3) Alert on solo old-key signatures during rotation.

AV-65 [HIGH]: Flash Loan Stake Domination Attack

Attack: Attacker flash-loans 100 ETH, stakes as keeper, dominates fee distribution for one high-value event, unstakes, repays loan. With 100x stake, earns 2x equal-split cap on a $10,000 event = $560 from a $35 flash loan cost.

Root Cause: No staking timelock, stake counts toward fee distribution immediately.

Cost to Attack: $35 per attempt (flash loan fee + gas).

Mitigation: Enforce 24-hour staking timelock before stake counts toward fee distribution. Flash loans must be repaid same-transaction, but stake isn't counted until 24h later. Also cap max stake at 10x minimum.

AV-66 [MEDIUM]: cancelRequest() Keeper Griefing

Attack: Attacker submits PoFR requests with minimum fee, lets keepers spend gas on entropy fetching and BLS signing, then cancels after 256-block timeout. Keepers waste gas; attacker gets full refund.

Root Cause: cancelRequest() refunds full fee to requester. Keepers who attempted fulfillment are not compensated.

Cost to Attack: $10 (100 x minimum fee, refunded) vs keepers' ~$50-100 gas loss.

Mitigation: (1) Charge 10% cancellation fee to keepers who attempted fulfillment. (2) Track fulfillment attempts on-chain. (3) Require separate deposit forfeited on cancellation.

AV-67 [MEDIUM]: Cross-Chain Fee Arbitrage via Native Asset Price Drift

Attack: AV-51 documents static native-asset fees that drift from intended USD prices. Attacker monitors all chain fees in USD and submits requests on the cheapest chain, paying below-intended fees.

Root Cause: Static native-asset amounts (0.2 TON, 0.5 ADA, etc.) don't track market prices.

Cost to Attack: $0 (exploits existing price discrepancies).

Mitigation: (1) Implement AV-51 fix: periodic fee repricing via price oracle. (2) Weekly TWAP-based adjustment. (3) Until implemented, document current USD fee ranges and acknowledge drift.

AV-68 [LOW]: Stake Concentration Cap Bypass via Smart Contract Wallets

Attack: 15% cap is per-address. Attacker deploys 10 smart contract wallets, each staking up to the cap, 10 x 10% = 100% is feasible. Different cloud providers for IP/ASN diversity.

Root Cause: Per-address enforcement cannot distinguish legitimate independent operators from attacker-controlled contract wallets.

Cost to Attack: $20,000-$60,000.

Mitigation: (1) Entity-level clustering: stake amounts, timing, IP/ASN, signing patterns. (2) Gitcoin Passport verification for keepers >5% stake. (3) Linked entities detection.

AV-69 [MEDIUM]: Non-EVM Contract-Specific Vulnerabilities

Attack: Same protocol in 5 languages (Solidity, Rust, Plutus, Tact, Move, ink!) creates 5 independent attack surfaces. TON/Tact is newest with weakest tooling. Off-chain BLS verification (TON, Cardano) means attacker can submit fabricated entropy with valid off-chain 'verification.'

Root Cause: Language-specific quirks: Solana compute unit limits, Plutus script size limits, Tact immature tooling, Move object model differences, ink! storage rent.

Cost to Attack: $50,000-$200,000 (security researcher time).

Mitigation: (1) Independent external audit for EACH non-EVM implementation. (2) For TON/Cardano: require 3-of-3 keeper attestation (not 2-of-n) since BLS is off-chain. (3) Fuzz testing per chain. (4) Use Sui's native BLS support.

AV-70 [LOW]: Integer Truncation in Hybrid Fee Model at Minimum Stake

Attack: At very small fees ($0.05) with many signers (25), the proportional portion of fee distribution may truncate to 0 in Solidity integer math. Large stakers get same as small stakers, proportional reward silently broken.

Root Cause: Solidity integer division truncates. Multiple divisions in the hybrid model (50% proportional, 50% equal, 2x cap) compound truncation.

Cost to Attack: $0 (natural occurrence).

Mitigation: (1) Use 1e18 fixed-point precision. (2) Minimum 1 wei per signer. (3) Skip proportional calculation for sub-$0.10 fees. (4) Test with minimum fee x minimum stake x maximum signers.

AV-71 [HIGH]: Silent Entropy Source Compromise (Signing Key Theft)

Attack: AV-47 addresses DNS hijacking. But if the entropy source's SIGNING KEY is compromised (nation-state level), the attacker produces valid-signed but fake entropy values. All 4 verification layers pass: valid signature, all keepers fetch same fake value, fraud proof uses the compromised key, and slashing doesn't apply because the values are 'valid.'

Root Cause: External entropy sources (NIST, ANU, Tor) rely on single-signature schemes. Compromising the signing key (not the server) bypasses all verification.

Cost to Attack: $10,000,000+ (nation-state level) or insider access.

Mitigation: (1) Multi-signature for entropy sources (if NIST supports it). (2) Cross-validation between independent sources. (3) Fetch from multiple mirrors and compare. (4) Document as residual risk: 5% per-source weight limit is primary mitigation. (5) Add second independent government beacon.

AV-72 [CRITICAL]: Founder $5M Wrench Attack (Single Point of Failure)

Attack: AV-50 discloses single-founder custody. This finding models the physical coercion vector: during Genesis, one person controls treasury keys, GitHub admin, Docker Hub publishing, all 10-12 genesis keepers, BLS key shares, and the pause multisig. A physical threat against one person compromises the ENTIRE protocol in minutes.

Root Cause: All critical infrastructure held by one human. Name is public in the whitepaper.

Cost to Attack: $50,000-$500,000 (physical threat, not technical).

Mitigation: IMMEDIATE, before mainnet: (1) Set up 3-of-5 treasury multisig. (2) Docker Hub org account with 2-of-3 approval. (3) Genesis keepers operated by 3+ independent parties. (4) Dead man's switch: if not cancelled in 7 days, treasury transfers to recovery multisig and protocol pauses. This MUST be resolved before mainnet, no exceptions.

AV-73 [MEDIUM]: Keeper Node Cold Boot Attack (BLS Key Extraction from Memory)

Attack: BLS keys loaded into RAM for signing. Attacker with physical access freezes RAM with cold spray, reboots from USB, dumps memory, extracts the BLS private key.

Root Cause: Unencrypted BLS key exists in process memory during signing.

Cost to Attack: $50 (cold spray + USB) + physical access.

Mitigation: (1) Use Apple Secure Enclave / Intel SGX / TPM for BLS signing, key never in main RAM. (2) Mac keepers: use Secure Enclave. (3) VPS: HSM or full-disk encryption with remote attestation.

AV-74 [MEDIUM]: Docker Hub Organization Account Compromise (Beyond AV-43)

Attack: AV-43 addresses individual credentials. But a Docker Hub ORG admin account compromise (via SIM swap or session hijack) allows adding collaborators and pushing signed malicious images using the org's Cosign key if it's OIDC-based.

Root Cause: Cosign key may be accessible via CI/CD OIDC pipeline. Org admin can add collaborators silently.

Cost to Attack: $10,000-$50,000 (SIM swap + social engineering).

Mitigation: (1) Cosign key on hardware device (YubiKey), not in CI/CD. (2) Audit logging on org changes with real-time alerts. (3) Rotate Cosign key every 90 days. (4) No SMS 2FA backup.

AV-75 [MEDIUM]: Time Synchronization Attack on Keeper Nodes (NTP Poisoning)

Attack: Keeper uses system clock to select DRAND round, NIST pulse, Tor consensus. Attacker poisons NTP, shifts clock back 60 seconds. Keeper fetches stale (but valid-signed) entropy values. Attacker who knows past values can predict the seed.

Root Cause: NTP is unauthenticated by default. Stale values have valid signatures.

Cost to Attack: $0-$5,000 (NTP poisoning requires network position).

Mitigation: (1) Use authenticated NTP (NTS). (2) Validate entropy freshness against block.timestamp. (3) Cross-validate system clock vs chain block time. (4) Alert on >5 second clock drift.

AV-76 [LOW]: Monitoring Stack Compromise, Attack Concealment

Attack: If monitoring (Grafana/Prometheus) runs on same host as keeper, host compromise also compromises monitoring. Attacker replaces metrics exporter with fake one, manipulates logs, hides malicious signing activity.

Root Cause: Monitoring is not protected as critical security infrastructure. Co-located with keeper.

Cost to Attack: $0 (requires host access).

Mitigation: (1) Monitoring on separate host. (2) Ship logs to remote append-only destination. (3) Signed heartbeat to remote monitoring service. (4) Tamper detection.

Round 7 Adversarial Audit Summary

23 new attack vectors identified (AV-54 through AV-76): 1 CRITICAL, 4 HIGH, 11 MEDIUM, 5 LOW, 2 additional LOW. CRITICAL: AV-72 (founder wrench attack). HIGH: AV-54, AV-59, AV-65, AV-71. Top priority fixes before mainnet: (1) AV-72: set up a 3-of-5 treasury multisig and distribute genesis keeper nodes to 3+ independent operators before launch; this is treated as a hard precondition, not a recommendation. (2) AV-59: verify individual BLS partial signatures on-chain, not just the aggregate. (3) AV-65: add a 24-hour staking timelock before stake counts toward fee distribution. (4) AV-54: redistribute stale source weight only to external sources, never to protocol-native Sources 13-15. (5) AV-71: document the residual risk of entropy source signing-key compromise and add cross-source validation.

29.12 Red Team Audit: Round 8: Node Fund Theft, Mobile Attacks, and Network Exploitation

Round 8 simulates a sophisticated hacker group targeting node operator funds, mobile light node users, and network infrastructure, areas not covered by Rounds 1–7. 16 new attack vectors were identified, including two unresolved CRITICAL findings.

AV-77 [CRITICAL]: withdraw() Function, Drain All Keeper Earnings via Compromised Keeper Address

Attack: The withdraw() function uses the pull-payment pattern, authenticating solely via msg.sender. If an attacker compromises a keeper's EVM private key (via key exposure, cold boot, malware, or social engineering), they can call withdraw() and drain ALL accumulated earnings. Worse, the unbonding period (7 days) means the attacker has a full week to drain earnings AND unstake the keeper's stake before the operator notices.

Root Cause: withdraw() authenticates solely via msg.sender, no multi-sig, no timelock, no second factor. Any entity holding the keeper's private key can withdraw ALL funds instantly. The pull-payment pattern is safe against reentrancy but NOT safe against key compromise.

Cost to Attack: $0 (requires prior key compromise, which has multiple vectors).

Mitigation: (1) Two-factor withdrawal: require withdrawal to a pre-registered withdrawal address set during registration. (2) Timelock on withdrawal address changes: 24-hour delay before a new address takes effect. (3) Withdrawal limit per day: max 50% of pending balance per 24 hours. (4) Alert the keeper via mobile app and email on any withdrawal attempt.

AV-78 [HIGH]: unstake() + claimUnstaked() Race, Stake Draining Before Slashing

Attack: A keeper who commits fraud (submits false entropy) can immediately call unstake() to initiate the 7-day unbonding period. Even though AV-31 gates unbonding on challenge window clearance, the attacker can front-run the slashing transaction using a private mempool (Flashbots), getting their stake back before slashing executes.

Root Cause: unstake() is permissionless. The 24-hour challenge window gates the CLAIM, not the initiation. An attacker who initiates unstaking immediately after fraud can race to claim before slashing executes.

Cost to Attack: $0 (requires keeper access + Flashbots).

Mitigation: (1) Lock stake during the challenge window: a keeper with an active challenge window cannot call claimUnstaked() until it expires. (2) Implement slashAndClaim() so slashing transactions get priority over unstake claims. (3) Delay claimUnstaked() by an additional 24 hours after unbonding ends.

AV-79 [HIGH]: Cross-Chain Stake Draining, Chain Hopping Attack

Attack: A keeper registered on multiple chains has independent stake on each chain. If the keeper's key is compromised, the attacker can drain stake from ALL chains simultaneously, but the operator only notices draining on one chain at a time, giving the attacker a head start on the rest.

Root Cause: Each chain has independent staking with no cross-chain coordination. There is no global kill switch to freeze a compromised keeper across all chains at once.

Cost to Attack: $0 (requires prior key compromise).

Mitigation: (1) Global kill switch: one emergency-freeze transaction on any chain freezes the keeper's stake and earnings across ALL chains via cross-chain messaging. (2) Mobile app alert when unstake is initiated on any chain. (3) Coordinated unstake requirements across chains.

AV-80 [MEDIUM]: FeeVault Balance Cap Auto-Distribution Exploitation

Attack: FeeVault triggers automatic distribution when balance exceeds 10x average daily fee volume. An attacker can manipulate this threshold by submitting many small requests to inflate the rolling average, then letting it drop before submitting a large request, timing auto-distribution to when they control the signing committee.

Root Cause: The auto-distribution threshold is based on a rolling average, which can be gamed by volume manipulation.

Cost to Attack: $10 (100 x minimum fee) + timing.

Mitigation: (1) Use a 30-day rolling average for the threshold. (2) Use a fixed USD cap instead of a dynamic one. (3) Exclude the triggering event's fee from the distribution calculation.

AV-81 [MEDIUM]: Gas Pool Accumulation with No Withdrawal Function, Permanent Fund Locking

Attack: The gas pool accumulates 10% of every fee but no withdrawal function is documented, meaning 10% of all protocol revenue is permanently locked in the contract. At scale this could amount to millions of dollars in trapped funds, creating pressure for a governance crisis that an attacker could exploit.

Root Cause: gasPool is incremented but never decremented. No withdrawGas() function is documented.

Cost to Attack: $0 (natural accumulation).

Mitigation: (1) Implement withdrawGas() with access controls, proportional to gas costs incurred. (2) Auto-sweep excess gas pool funds above a threshold to active keepers. (3) Cap the gas pool at a fixed amount, with excess flowing to treasury.

AV-82 [HIGH]: Mobile App Seed Phrase Extraction via Clipboard Injection

Attack: The mobile app uses a unified BIP-39 seed phrase from which all chain-specific keys are derived. If the user copies their seed phrase to the clipboard during backup, a malicious app on the phone can read the clipboard and extract the seed phrase, gaining access to ALL chain keys, staking funds, and earnings.

Root Cause: iOS and Android allow apps to read clipboard contents. Many users ignore the clipboard-access banner. If the seed phrase is ever copied for backup, it is exposed.

Cost to Attack: $0 (requires a malicious app on the user's phone).

Mitigation: (1) Never allow seed phrase copy to clipboard, display on-screen only with a 'write down manually' warning. (2) Use iOS Secure Enclave for seed phrase storage. (3) If clipboard copy is ever necessary, auto-clear after 30 seconds. (4) Warn the user if another app accesses the clipboard during seed phrase viewing.

AV-83 [HIGH]: Mobile Light Node Gossip Relay Spam, Network Flooding via Emulated Phones

Attack: AV-13 made entropy submissions advisory-only, but the gossip relay function is still active. An attacker can spin up thousands of emulated mobile light nodes on cloud Android emulators and flood the gossip network with relay spam, degrading performance for legitimate keepers while still earning the 2% relay fee share.

Root Cause: Light nodes participate in gossip relay with minimal barriers. AV-13 made entropy advisory-only, but the relay function itself can still be abused for network flooding.

Cost to Attack: $50/hour (1,000 cloud Android instances).

Mitigation: (1) Rate-limit gossip relay per light node to a maximum messages-per-second. (2) Require the AV-K-05 anti-spam deposit before gossip relay is enabled. (3) Reputation system with bans and deposit forfeiture for excessive/invalid relay. (4) Cap keeper connections to light nodes.

AV-84 [CRITICAL]: Mobile Wallet Transaction Signing, Biometric Bypass via Accessibility Services

Attack: The mobile app uses biometric authentication for transaction signing, but Android Accessibility Services can bypass biometric prompts by programmatically clicking the confirm button. A malicious accessibility app can approve transactions without the user's actual biometric input.

Root Cause: Android Accessibility Services have privileged UI access. A malicious app with accessibility permissions can read screen contents, click buttons, and fill forms, bypassing app-level (not OS-level) biometric prompts.

Cost to Attack: $0 (requires a malicious app on the user's phone).

Mitigation: (1) Use the Android BiometricPrompt API with CryptoObject, ties the biometric to the cryptographic operation and cannot be bypassed by accessibility services. (2) On iOS, use deviceOwnerAuthenticationWithBiometrics with no passcode fallback for financial transactions. (3) Detect active accessibility services and require additional authentication, or disable signing entirely while they're active.

AV-85 [HIGH]: Mobile-to-Desktop API Key Theft via MITM on Local Network

Attack: The mobile app communicates with the desktop keeper node via a per-device API key. If the desktop keeper's API is on a shared local network without enforced TLS, an attacker on the same network can intercept the API key via a man-in-the-middle attack and gain read access to node status, earnings, and configuration.

Root Cause: The mobile-to-desktop API connection doesn't clearly enforce TLS. If bound to a local network IP rather than localhost, traffic may be unencrypted.

Cost to Attack: $0 (requires same-network access).

Mitigation: (1) Enforce HTTPS with a self-signed certificate generated and pinned during QR pairing. (2) Bind port 3000 to 127.0.0.1 only, enforced in code, not just documentation. (3) Require WireGuard or Tor hidden service for any remote access, never raw HTTP on a local network. (4) Bind the per-device API key to the specific pinned TLS certificate.

AV-86 [MEDIUM]: Mobile Light Node Battery Drain Griefing via Keeper-Induced Polling

Attack: Light nodes are designed to use under 2% battery per day, but if keepers broadcast events at high frequency, light nodes must wake up to relay each one, draining battery far beyond target. An attacker who controls keepers can grief mobile users by generating excessive events.

Root Cause: Light nodes wake on every gossip message to check whether they need to relay. High event frequency means frequent wakeups and battery drain.

Cost to Attack: $10 (100 x minimum fee) + keeper access.

Mitigation: (1) Adaptive polling: light nodes poll at most once every 5 minutes regardless of gossip frequency. (2) Event batching for notifications. (3) Enforce existing per-address rate limiting. (4) Offer a battery-saver mode that relays only 1 in 10 messages.

AV-87 [MEDIUM]: Mobile App Deep Link / URL Scheme Hijacking

Attack: The mobile app likely uses deep links or URL schemes for verification links. An attacker can register a similar scheme or use a deep link to redirect users to a phishing app that mimics the RandProof interface and captures seed phrases or transaction approvals.

Root Cause: Deep links and URL schemes are not cryptographically authenticated by default. Any app can register the same scheme.

Cost to Attack: $500 (developer account + fake app).

Mitigation: (1) Use Android App Links and iOS Universal Links, which are cryptographically verified and prevent hijacking. (2) Never request the seed phrase through a deep-link flow, entry only available from the main Settings menu. (3) Display a security banner on deep-link entry warning that RandProof will never ask for a seed phrase.

AV-88 [LOW]: Mobile Light Node Earnings Dust, Unclaimable Micro-Balances

Attack: Light nodes earn a small percentage of fees per event. At realistic volumes, balances accumulate slowly, and on higher-gas chains (notably Ethereum mainnet) withdrawal gas cost can exceed the accumulated balance indefinitely, permanently trapping a user's earnings.

Root Cause: Light node earnings are micro-scale. Gas costs for withdrawal can exceed earnings until a large balance accumulates, which may never happen on expensive chains.

Cost to Attack: $0 (natural occurrence, amplified by AV-52 on native-asset chains).

Mitigation: (1) Hide the withdraw action until balance exceeds a minimum threshold or 10x gas cost. (2) Batch withdrawals across events and chains. (3) Settle light node earnings on the cheapest available chain rather than Ethereum mainnet.

AV-89 [HIGH]: Gossip Network Partition Attack, Chain Splitting via Network-Level Eclipse

Attack: AV-14 resolved gossip eclipse attacks at the application layer, but a network-level partition attack bypasses application-layer protections entirely. An attacker who controls a BGP router or ISP can partition the keeper network by dropping connections between specific IP ranges, causing keepers in different partitions to sign different events with different entropy.

Root Cause: Application-layer peer selection doesn't protect against network-layer partitioning. If an ISP or BGP-level attacker drops traffic between regions, the full-mesh topology is broken at the network layer even though it appears connected at the application layer.

Cost to Attack: $100,000-$1,000,000 (BGP hijacking or ISP-level access).

Mitigation: (1) Heartbeat protocol: keepers send signed heartbeats and pause signing if they lose contact with more than half their peers. (2) Require cross-region quorum during partitioned mode. (3) Geographic diversity requirement for the genesis keeper set. (4) Automatically freeze fee distribution and trigger investigation if two valid fulfillments appear for the same event.

AV-90 [MEDIUM]: RPC Provider Correlation Attack, Single Provider Controls Multiple Entropy Sources

Attack: AV-37 recommends dedicated RPC providers, but doesn't require diversity across providers. If a keeper uses one provider for all chains, that provider becomes a single point of failure or corruption, able to feed fake block data for multiple entropy sources simultaneously.

Root Cause: Requiring 'dedicated' RPC providers doesn't require diversity across them. Using one provider for all chains creates a hidden correlation.

Cost to Attack: $1,000,000-$10,000,000 (compromise a major RPC provider internally).

Mitigation: (1) Require keepers to use 2+ RPC providers from different companies and cross-check block data. (2) For on-chain sources, the contract reads directly and RPC is irrelevant. (3) For off-chain multi-chain hashes, fetch from 2+ providers and verify they match before submitting.

AV-91 [MEDIUM]: Keeper Node SSH Compromise via Default/Weak Credentials

Attack: The node operator runbook doesn't explicitly document SSH hardening. VPS-based operators using default SSH configs (password auth, port 22, root login) are vulnerable to automated brute-force bots that scan the internet continuously, leading to full host compromise and key theft.

Root Cause: The runbook assumes operators know to harden SSH but doesn't make it explicit. VPS users are especially exposed; home users less so.

Cost to Attack: $0 (automated bots scan the internet continuously).

Mitigation: (1) Add an explicit SSH hardening section to the runbook: disable password auth and root login, use key-based auth only, change the default port, install fail2ban. (2) Add a security checklist to the setup wizard that verifies SSH config before allowing node start. (3) Refuse to start the keeper if insecure SSH config is detected.

AV-92 [LOW]: Keeper Docker Container Escape via Privileged Mode Misconfiguration

Attack: If an operator runs the keeper container with the --privileged flag (sometimes suggested as a troubleshooting workaround), a vulnerability in the container runtime or keeper software could allow a full container escape and host compromise.

Root Cause: The documented run command doesn't use --privileged, but operators may add it when troubleshooting, with no warning against doing so.

Cost to Attack: $0 (requires a keeper software vulnerability plus a misconfigured container).

Mitigation: (1) Add an explicit warning against --privileged in the runbook, recommending --cap-add for specific capabilities only. (2) Run the container as a non-root user internally. (3) Refuse to start if privileged mode is detected. (4) Use restrictive Docker security options by default.

Round 8 Red Team Audit Summary

16 new attack vectors identified (AV-77 through AV-92): 2 CRITICAL (AV-77, AV-84), 6 HIGH (AV-78, AV-79, AV-82, AV-83, AV-85, AV-89), 6 MEDIUM (AV-80, AV-81, AV-86, AV-87, AV-90, AV-91), 2 LOW (AV-88, AV-92). Top priority fixes before mainnet: (1) AV-77: pre-registered withdrawal address with a 24-hour timelock on changes and a daily withdrawal limit. (2) AV-84: Android BiometricPrompt with CryptoObject binding, since accessibility services cannot bypass cryptographic biometric binding. (3) AV-78: lock stake during the challenge window and give slashing transactions priority over unstake claims. (4) AV-79: a global kill switch that freezes a compromised keeper across all chains from a single transaction. (5) AV-82: disable seed phrase clipboard copy entirely. (6) AV-85: enforce HTTPS and certificate pinning on the mobile-to-desktop API, with port 3000 bound to localhost only.

29.13 Red Team Audit: Round 9: Client Integration, Payment Layer, Wallet, Governance, and Cross-Chain Attacks

Round 9 targets client smart contract integrations, USDC and payment settlement, the unified wallet architecture, governance parameter risk, and cross-chain coordination gaps, areas not covered by Rounds 1–8. 15 new attack vectors were identified.

AV-93 [HIGH]: Malicious Client Contract, fulfillRandomness() Reentrancy Draining

Attack: The KeeperCoordinator calls back to the integrating client contract during fulfillment. A malicious client contract can use this callback to re-enter the Coordinator, cancelling other pending events, spawning floods of new requests, or re-entering withdraw() if the attacker is also a keeper.

Root Cause: The Coordinator performs an external call to an untrusted client contract during fulfillment. The Checks-Effects-Interactions pattern protects internal state but doesn't prevent cross-function reentrancy through this callback.

Cost to Attack: $0.10 (minimum fee for one request).

Mitigation: (1) Use a reentrancy guard on the fulfillRandomness() callback: the Coordinator sets a fulfilling flag before calling the client and reverts any Coordinator call made during that window. (2) Alternatively, don't push the result to the client at all, store it on-chain and let the client pull it via a getter.

AV-94 [HIGH]: Fake KeeperCoordinator Deployment, Address Spoofing on Non-EVM Chains

Attack: Non-EVM chains (Solana, TON, Cardano, Sui) lack a documented canonical address registry. An attacker could deploy a fake Coordinator that mimics the real interface but always returns attacker-chosen seeds, and promote it via a typosquatted docs site, leading clients to integrate with the wrong contract entirely.

Root Cause: No canonical, verified address registry is published across all 17+ chains. Clients must locate the correct address themselves.

Cost to Attack: $50-$500 (deploy a fake contract on a cheap chain plus a phishing site).

Mitigation: (1) Publish canonical Coordinator addresses at a DNSSEC-protected, HTTPS URL. (2) Use deterministic CREATE2 deployment on EVM chains for a consistent address. (3) Hardcode verified addresses in the official SDK rather than accepting user-supplied addresses. (4) Have the SDK verify the deployed address against the published registry and warn on mismatch.

AV-95 [MEDIUM]: Client-Side Modulo Bias Exploitation in Winner Selection

Attack: AV-10 documents modulo bias and offers rejection sampling as an option, but most clients will use the simple default modulo operation. With large entrant counts, the bias becomes statistically significant and compounds at scale across many raffles.

Root Cause: Rejection sampling is offered as optional rather than enforced as the default.

Cost to Attack: $0 (exploits the default modulo operation).

Mitigation: Make rejection sampling the default behavior: the Coordinator computes a bias-free winner index internally and returns that, rather than handing clients a raw seed to reduce themselves.

AV-96 [MEDIUM]: Event ID Collision Across Chains, Cross-Chain Fulfillment Confusion

Attack: Event IDs are client-generated and not guaranteed unique across chains. If the Coordinator's signature message construction or event tracking doesn't strictly bind chainId, a fulfillment intended for one chain could potentially be replayed against a same-named event on another chain.

Root Cause: The BLS signing message includes chainId, but event tracking and collision handling depend on that binding being enforced correctly and consistently across all chain implementations.

Cost to Attack: $0.10 (submit one request on each chain).

Mitigation: (1) Ensure chainId is always the first field in the signed message, verified at the contract level. (2) Include the Coordinator's own contract address in the signed message, since different chains have different addresses. (3) Have the SDK append chainId to client-provided event IDs automatically.

AV-97 [HIGH]: USDC Approval Front-Running, Infinite Allowance Exploitation

Attack: If a client uses an infinite USDC approval for gas savings, any future vulnerability in the Coordinator's transfer logic, or a spoofed Coordinator address (AV-94), could drain the client's entire USDC balance rather than just the fee for one event.

Root Cause: Exact allowance amounts aren't specified; infinite approvals are a common but risky pattern for gas savings.

Cost to Attack: $0 (exploits an existing infinite approval).

Mitigation: (1) The Coordinator should only ever pull the exact fee amount. (2) The official SDK should default to exact, per-event approvals rather than infinite ones. (3) Support ERC-2612 permit() for gasless exact approvals.

AV-98 [HIGH]: CCTP V2 Burn-and-Mint Failure, Treasury Funds Lost in Transit

Attack: Treasury consolidation via CCTP V2 burns USDC on the source chain and mints on Base, relying on Circle's attestation service. If that service has an outage or the attestation message expires, funds can be burned without ever minting, permanently losing them.

Root Cause: CCTP V2, while more trusted than a typical third-party bridge, is still a single-organization dependency for treasury consolidation, with no documented fallback if attestation fails.

Cost to Attack: $0 (requires a CCTP V2 outage, natural or induced).

Mitigation: (1) Require manual or governance-confirmed consolidation rather than auto-burning. (2) Require multisig confirmation of the mint before the burn is initiated. (3) If attestation fails after 24 hours, hold funds on the source chain rather than re-attempting indefinitely.

AV-99 [MEDIUM]: Native Asset Settlement, Price Manipulation via MEV Sandwich

Attack: On chains settling fees in native assets, an MEV searcher can sandwich the fulfillment transaction around a price move, extracting a small amount of value from each fee. The effect per transaction is minor but compounds at scale.

Root Cause: Native asset fees are static quantities; the USD value at fulfillment time can differ from request time due to MEV-driven price movement.

Cost to Attack: $0 (MEV extraction is self-funding).

Mitigation: This is a minor, accepted issue at current scale. For high-value events, recommend USDC-settlement chains instead of native-asset chains.

AV-100 [MEDIUM]: Fee Payment to Wrong Chain, Cross-Chain USDC Confusion

Attack: A client contract deployed on multiple chains must manage USDC approvals independently per chain. A missing approval on one chain causes fulfillment requests on that chain to revert or stall until timeout, which can cause widespread failures if a multi-chain deployment is misconfigured.

Root Cause: Multi-chain deployment requires per-chain approvals with no automatic cross-chain awareness.

Cost to Attack: $0 (misconfiguration, not an active attack).

Mitigation: (1) Have the SDK check allowance before submitting a request and fail with a clear error if insufficient. (2) Offer an auto-approve pattern that combines approval and the request call in one transaction. (3) Document that clients must approve USDC on each chain they operate on.

AV-101 [HIGH]: Unified BIP-39 Seed, Single Point of Failure for All Chains

Attack: The mobile app derives keys for every supported chain from one BIP-39 seed phrase. If that seed is compromised through any vector, the attacker gains simultaneous access to stake, earnings, and deposits across every chain at once, with no per-chain isolation.

Root Cause: Convenience (one seed for all chains) creates a single point of failure, with no documented option for key isolation or multi-signature protection for high-value keepers.

Cost to Attack: $0-$500 (various seed extraction vectors).

Mitigation: (1) Offer an advanced option for separate per-chain keys. (2) Require hardware wallet support for keepers with total stake above a threshold. (3) Require multi-sig withdrawal for high-value keepers. (4) Support social recovery via a pre-registered guardian address that can freeze a keeper.

AV-102 [MEDIUM]: Transaction Signing Without Gas Price Validation, Fee Drain via High Gas Price

Attack: If the mobile app signs transactions using the gas price suggested by the connected RPC without independent validation, a compromised or malicious RPC could suggest an abnormally high gas price, consuming the user's entire transaction value in fees.

Root Cause: Gas price typically comes from the connected RPC; without cross-validation against an independent source, a compromised RPC can manipulate it freely.

Cost to Attack: $0 (requires a compromised RPC or validator).

Mitigation: (1) Validate gas price against an independent oracle and warn the user if the RPC's suggestion is far above it. (2) Cap signable gas price relative to a recent average. (3) Use EIP-1559 transactions with an explicit maxFeePerGas cap.

AV-103 [MEDIUM]: Mobile Wallet Key Derivation Path Collision Across Chains

Attack: If two of the 17+ supported chains were ever assigned the same or overlapping BIP-44 derivation path, the same private key would control funds on both chains, and a public address on one chain could let an attacker derive the key for the other.

Root Cause: Exact derivation paths for all 17+ chains aren't documented in the whitepaper, and some chains use non-standard paths.

Cost to Attack: $0 (exploits a path collision, if one exists).

Mitigation: (1) Document the exact, unique, hardened derivation path for each chain. (2) Verify no two chains share a path. (3) Test-derive keys for all chains from one seed and confirm all resulting addresses are unique before each new chain integration.

AV-104 [HIGH]: Protocol Parameter Update via Governance, Unintended Consequence Attack

Attack: A seemingly benign governance proposal, such as increasing committee size without increasing the signing threshold proportionally, could quietly weaken security. The 7-day timelock gives time for review, but complex parameter interactions may not be obvious to voters evaluating the proposal in isolation.

Root Cause: No formal, automated parameter-impact analysis process is documented for governance proposals.

Cost to Attack: $0 (a governance proposal is free to submit).

Mitigation: (1) Require an automated security-impact simulation (Nakamoto coefficient, attack cost, committee-capture probability) attached to every proposal before submission. (2) Require independent review for parameter changes above a defined magnitude threshold. (3) Publish simulation results alongside the proposal for voters.

AV-105 [MEDIUM]: Cross-Chain State Desynchronization, Keeper Registry Drift

Attack: Each chain maintains an independent keeper registry. If a chain has far fewer registered keepers than another (e.g., a more complex non-EVM chain), its effective committee size and security level can be much weaker, letting an attacker cheaply acquire a large share of a thin keeper set.

Root Cause: No cross-chain keeper registry synchronization or minimum-keeper enforcement is documented.

Cost to Attack: $100-$300 (a handful of nodes on a thinly-staffed chain).

Mitigation: (1) Reduce the fee tier and display a reduced-security warning on chains below a minimum keeper count. (2) Offer a bonus to keepers who register on all supported chains. (3) Publish a public per-chain keeper-count dashboard. (4) Pause fulfillments on a chain entirely if its keeper count falls below a safe minimum.

AV-106 [MEDIUM]: Emergency Pause on One Chain Doesn't Pause Others, Cross-Chain Inconsistency

Attack: The emergency circuit breaker pauses fulfillments on one chain at a time. If a vulnerability is discovered and exploited, an attacker can continue exploiting the same vulnerability on every other chain while signers work through pausing each one individually.

Root Cause: The pause function is per-chain, with no documented global pause mechanism.

Cost to Attack: $0 (exploits the time window between sequential per-chain pauses).

Mitigation: (1) Implement a global pause that propagates to all chains within one block via cross-chain messaging. (2) Provide a single 'pause all' action in the operator-facing tooling. (3) Document both the global and per-chain pause options clearly.

AV-107 [LOW]: Keeper Software Version Drift, Protocol Forking via Update Delay

Attack: With no forced upgrade mechanism, keepers update on their own schedule. If a release changes entropy-fetching or signing behavior, keepers running different versions concurrently can submit diverging values, degrading multi-keeper attestation until everyone updates.

Root Cause: No documented minimum-version enforcement or forced upgrade window.

Cost to Attack: $0 (a natural occurrence from update delays).

Mitigation: (1) Have keepers report their software version on-chain at registration. (2) Have the Coordinator reject fulfillments from keepers below a minimum supported version. (3) Define an upgrade window (e.g., 14 days) after which outdated keepers are automatically deactivated.

Round 9 Red Team Audit Summary

15 new attack vectors identified (AV-93 through AV-107): 0 CRITICAL, 6 HIGH (AV-93, AV-94, AV-97, AV-98, AV-101, AV-104), 8 MEDIUM (AV-95, AV-96, AV-99, AV-100, AV-102, AV-103, AV-105, AV-106), 1 LOW (AV-107). Top priority fixes: (1) AV-93: a reentrancy lock on the fulfillRandomness() callback. (2) AV-94: a canonical, SDK-hardcoded Coordinator address registry. (3) AV-97: exact-amount USDC approvals only, no infinite allowances. (4) AV-98: manual confirmation for CCTP V2 treasury consolidation, no auto-burn without a confirmed mint path. (5) AV-101: hardware wallet support for keepers above a stake threshold, to break the single-seed single point of failure.

AV-108 [MEDIUMIMPLEMENTED v3, PRE-AUDIT]: Unsigned External Source Forgery (ANU QRNG, Tor Consensus), Multi-Keeper Attestation Filter

Attack: Sources without a cryptographic signature RandProof can verify on-chain (ANU QRNG; Tor Consensus Hash unless and until on-chain RSA verification is built) can only be checked for plausibility, not proven genuine, from a single keeper's report. At Phase 2+, when keeper registration is permissionless, a malicious keeper could submit a fabricated value for an unsigned source and the contract would have no cryptographic way to detect it from that report alone. This is a distinct attacker from the Genesis-phase trust model already disclosed in Section 24.1, since at Phase 2+ the keeper is no longer one of a small, founder-selected set.

Root Cause: Verification of these sources depends entirely on the honesty of whichever keeper fetched and reported the value; there is no signature for the contract to check independently.

Cost to Attack: $0 (requires only keeper registration once permissionless registration is live).

Mitigation: Multi-keeper attestation, applied explicitly to unsigned sources: at least 3 independently-ASSIGNED keepers fetch the same unsigned source separately for the same event. A keeper cannot predict what an honest, independent measurement will return, so fabricating a value that matches what other keepers will report is exactly as hard as guessing the genuine output. If a 2-of-3 majority agrees, that value is accepted. If reports disagree, the contract treats this as a fraud signal: the source's weight is dropped to zero for that event (redistributed per AV-54's external-only rule, never to protocol-native Sources 13-15), and the disagreeing keeper enters the standard 24-hour fraud-proof challenge window. A keeper confirmed to have submitted a mismatched value forfeits a bonded amount; repeated mismatches trigger stake slashing, and resolving a dispute now pays the resolver a share of the forfeited bonds so disputes do not sit open indefinitely. This mechanism is implemented as a standalone Solidity module, EntropyAttestation.sol v2, with 24 passing unit tests covering the 2-of-3 accept path, the full 1-1-1 dispute path, bond forfeiture, slash escalation, the withdrawal path, and 3 direct regressions confirming the 5 findings from the pre-deployment audit (see Status below) are closed. Reporters must be explicitly assigned by an authorized assigner before they may report, they can no longer self-select. The module is staged for Base Sepolia testnet deployment, not yet wired into KeeperCoordinator.sol's event-fulfillment flow, and should be implemented identically for any other unsigned source RandProof adds in the future.

Status: IMPLEMENTED v3, PRE-AUDIT, v1 of EntropyAttestation.sol (16/16 passing tests) was reviewed in a pre-deployment audit before any deployment occurred. That audit found 5 real issues directly against the deployed bytecode, not just by inspection: (1) CRITICAL, no withdrawal function existed; staked ETH was permanently locked. (2) HIGH, any registered keeper could self-select into an event's 3 reporters by simply calling submitReport() first, enabling free collusion. (3) HIGH, resolveDispute() had no caller incentive, so disputes could sit open forever with stakes never actually forfeited. (4) MEDIUM, registerKeeper() had no cap, enabling free Sybil registration. (5) MEDIUM, the admin role was declared but gated nothing. All 5 were fixed in v2. A second round (Round 10, Section 29.14) then attacked v2's own fixes and found 3 more: AV-109 (the assigner could repeatedly pick the same 3 keepers, making collusion permanent rather than one-time), AV-110 (admin role changes took effect instantly with no timelock), and AV-111 (the assigner could name itself as a reporter). All 8 findings across both rounds are fixed in v3, with 31 passing tests including direct regressions for each. v3 is staged for Base Sepolia testnet deployment (see the project's DEPLOYMENT.md) but has not yet been integrated into KeeperCoordinator.sol (Section 19), which now exists as a tested MVP but does not yet call into this contract, and has not had an external security audit. Two residual risks remain disclosed rather than fixed: the assignment cooldown raises the bar against reusing the same 3 keepers but does not guarantee unpredictable selection across a small rotating set, which depends on KeeperCoordinator's eventual VRF-based committee selection; and the 24-hour role-change timelock buys a reaction window against a brief admin-key compromise but not a sustained one, for which the 3-of-5 multisig and dead man's switch already disclosed under AV-72 remain the real precondition. Applies specifically once keeper registration becomes permissionless (Phase 2+); during Genesis, this risk is subsumed by the already-disclosed federated trust model (Section 24.1, AV-50).

29.14 Red Team Audit: Round 10: Adversarial Review of EntropyAttestation.sol and the Testnet Deployment Plan

Round 10 targets the actual code that exists as of this writing, EntropyAttestation.sol v2 (the AV-108 mitigation) and its staged Base Sepolia testnet deployment plan, rather than the broader whitepaper specification. This is the first audit round in this document's history to review real, deployed-tested code rather than a design description, and it found 3 new issues by attacking the v2 fixes themselves, confirmed by live exploit tests against the actual contract bytecode, the same standard applied throughout this audit log.

AV-109 [HIGH]: Assigner Can Repeatedly Pick the Same 3 Keepers, Making Collusion Permanent Rather Than One-Time

Attack: AV-108's v2 fix correctly stopped keepers from self-selecting into a report set, but moved the trust problem onto whoever controls the authorizedAssigner role, which had no rotation or diversity requirement at all. Confirmed by live test: nothing prevented the same 3 addresses being assigned to every single event. If the assigner is careless or compromised, the 'three independent keepers' property degrades from a one-time collusion risk into a standing one, since the same three colluding parties can simply be re-assigned together indefinitely.

Root Cause: Closing free self-selection (the v2 fix) is necessary but not sufficient -- it does not by itself make WHICH three keepers get assigned unpredictable. That property has to come from the assignment mechanism itself, which v2 left fully open.

Cost to Attack: $0 (requires only control or carelessness of the assigner role, not a separate exploit).

Mitigation: A 1-hour cooldown (ASSIGNMENT_COOLDOWN) now applies after a keeper is released from an assignment before they can be assigned again, implemented and confirmed by a live test showing immediate re-assignment now reverts with CooldownNotElapsed. This makes 'always use the same 3 keepers' structurally impossible rather than merely discouraged. It does not by itself guarantee unpredictable selection across a small rotating set (e.g. alternating among 6 keepers) -- that is the responsibility of real VRF-based committee selection inside KeeperCoordinator once it exists; the cooldown is a cheap structural floor underneath that, not a replacement for it.

AV-110 [HIGH]: Instant, Untimelocked Admin Control Over the Assigner Role

Attack: v2's setAuthorizedAssigner() and setRegistrationCap() took effect in the same transaction with no delay. Confirmed by live test: a single admin transaction redirects all future assignment power immediately, with no timelock, no second confirmation, and no grace period for monitoring tooling or the genesis team to react. Combined with AV-109, a compromised or coerced admin key does not need to attack the contract's core logic at all -- it can simply repoint the assigner role to an attacker-controlled address and then assign that address into every future event.

Root Cause: No timelock existed on role-defining admin actions, even though the rest of the codebase (and the broader whitepaper) uses 24-hour and 7-day delay conventions elsewhere for comparable risk. This is the same class of risk as AV-72 (the founder wrench attack) already disclosed elsewhere in this audit log, but it is a new, specific instance of it inside this particular contract that did not exist before the assigner role was introduced in v2.

Cost to Attack: $0 (requires admin key compromise, which has its own cost modeled under AV-72).

Mitigation: Both setAuthorizedAssigner() and setRegistrationCap() are replaced with a queue-then-execute pattern: queueAssignerChange() / queueRegistrationCapChange() submit a pending change that only takes effect after a 24-hour timelock and an explicit executeRoleChange() call, with cancelRoleChange() available if a change was queued by mistake. This buys a real reaction window rather than instant effect. The emergency pause switch (setPaused()) deliberately remains untimelocked and instant, since an emergency stop that takes 24 hours to activate defeats its own purpose -- pausing and role changes are different risk classes and are handled differently on purpose.

AV-111 [MEDIUM]: The Authorized Assigner Could Name Itself as One of the 3 Reporters

Attack: assignReporters() did not check whether the calling assigner's own address appeared in the list of 3 reporters being assigned. Confirmed by live test: the assigner could successfully assign itself as one of the three. If the assigner and a keeper are controlled by the same party (plausible at Genesis, or if the assigner role is ever compromised), this reduces genuine independence from 3 separate voices to effectively 2, since the third 'independent' report is actually self-interested.

Root Cause: No self-assignment check existed in the original assignment logic.

Cost to Attack: $0 (requires only that the assigner is also a registered keeper, which is not prevented anywhere else).

Mitigation: assignReporters() now reverts with AssignerCannotBeReporter() if the caller's own address appears anywhere in the 3-address reporter list, confirmed by a live test. This is a narrow, cheap check that closes the specific gap without requiring the assigner and keeper roles to be structurally separated, which may not always be possible or desirable depending on how KeeperCoordinator's committee selection eventually works.

AV-112 [HIGHIMPLEMENTED, PRE-AUDIT]: Genesis-Phase Committee Censorship Has No Cost or Hard Ceiling

Attack: AV-48 closes the case where a keeper privately computes an outcome before deciding whether to publish it. It does not close the simpler case of a keeper, or a colluding group controlling the signing threshold, simply refusing to sign at all. At Genesis (12 nodes, t=3, Nakamoto coefficient 4, Section 24.1), a party controlling enough of the genesis set can occupy or stall signing slots indefinitely, since today refusing to sign costs the censoring keeper nothing -- the only consequence is a delayed event for the requester, who can eventually call cancelRequest() after the 256-block timeout for a refund. The committee-scaling formula (AV-58) and the 15% stake cap (also AV-58's mitigation) both depend on the network having grown past Genesis to meaningfully dilute attacker control; neither helps today, since randomly selecting among a small, possibly attacker-dominated pool does not dilute control the way it does at 1,000 nodes.

Root Cause: Liveness was protected (cancelRequest() with a timeout) but censorship itself was never made costly to the censoring party, and no mechanism existed to retry a censored event with a disjoint set of signers before falling back to a refund.

Cost to Attack: $0 (requires only controlling enough of the genesis keeper set to occupy signing slots, which Section 24.1 and AV-50 already disclose as a present, not hypothetical, Genesis-phase condition).

Mitigation: Two mechanisms, detailed in full in Section 23.1.5 and implemented and tested as LivenessGuard.sol: (1) a disjoint fallback committee that automatically reassigns a stalled request to a second committee excluding every member of the first, failed one, rather than waiting on the same committee or falling straight through to a refund; (2) a non-fulfillment counter tracked per keeper, independent of any fraud-dispute outcome, that escalates to bond forfeiture and slashing for keepers whose assigned-but-silent rate crosses a defined threshold within a rolling window -- applying the same bond-and-slash shape already built and tested for false-report mismatches in EntropyAttestation.sol (AV-108-111) to sustained silence instead. The contract additionally pays whoever triggers the stall-detection function a 5% share of the forfeited bonds, the same resolver-incentive shape AV-108's resolveDispute() uses. Both mechanisms reduce how much damage a captured committee can do and for how long, at every phase including Genesis; neither substitutes for the genesis-keeper-diversity precondition already disclosed under AV-72, and this document does not claim they do.

Status: IMPLEMENTED, PRE-AUDIT. Both mechanisms are specified in Section 23.1.5 with the same precision as every other forward-looking design in this document, and are now implemented and tested as LivenessGuard.sol (22 passing tests, 6 adversarial probes, see Section 29.13 and Section 29.17 for the full audit history). LivenessGuard.sol is staged for Base Sepolia testnet deployment but has not yet been integrated with KeeperCoordinator.sol (Section 19), which now exists as a tested MVP but does not yet call into this contract, and has not had an external security audit. Applies at every phase, but is most severe during Genesis, where committee size is smallest and the federated trust model already disclosed under Section 24.1 and AV-50 makes capture most plausible.

Round 10 Audit Summary

3 new findings (AV-109 through AV-111), all found by attacking the fixes introduced in the prior pre-deployment audit (AV-108) rather than the original AV-108 gap itself. 2 HIGH (AV-109, AV-110), 1 MEDIUM (AV-111). All 3 are fixed in EntropyAttestation.sol v3, each with a direct regression test confirming the original exploit no longer works. Two additional LOW-severity, documentation-only items were also identified and closed without code changes: an operator-facing note about registration-cap behavior when lowered below the current registered count, and an explicit comment confirming no defaultNetwork is configured toward Base mainnet, so an operator who omits --network cannot accidentally deploy to a live chain. EntropyAttestation.sol now has 31 passing tests across two audit rounds (8 total findings, all closed with regression tests) and is staged for Base Sepolia testnet deployment via a documented Hardhat Ignition module and runbook. It remains true, and is disclosed as such rather than implied otherwise, that: (1) the contract is not yet integrated into KeeperCoordinator.sol (Section 19), which now exists as a tested MVP but does not yet call into this contract; (2) it has not had an external professional security audit; (3) the AV-109 cooldown fix raises the bar against repeated reuse of the same three keepers but does not by itself guarantee unpredictable committee selection, which depends on KeeperCoordinator's eventual VRF-based assignment logic; and (4) the AV-110 timelock buys a 24-hour reaction window against a compromised admin key but does not solve a sustained compromise, which is why the 3-of-5 treasury multisig and dead man's switch disclosed under AV-72 remain a separate, harder precondition for mainnet regardless of this contract's own protections.

29.15 Red Team Audit: Round 11: RandProofAutomation.sol

Round 11 reviews RandProofAutomation.sol (Section 10), the general-purpose decentralized upkeep registry, before any deployment. This is the third contract in this product family (after EntropyAttestation.sol and LivenessGuard.sol) to go through this specification-then-implementation-then-adversarial-review process before touching a testnet, and the first round in this document's history where the adversarial pass found an issue serious enough that an unguarded test run hung rather than failing cleanly -- a finding confirmed by directly timing the unguarded and guarded versions against each other, not merely by reading whether a test passed.

AV-113 [MEDIUMDOCUMENTED, FIXED]: Unbounded Reentrant Calls into RandProofAutomation

Attack: During RandProofAutomation.sol's pre-deployment adversarial review, a malicious client's performUpkeep was found able to call back into the registry's own performNativeUpkeep for itself, attempting a second fee claim within the same call stack. Confirmed by direct test: the unguarded version did eventually revert and roll back cleanly (no funds were lost), but only because the EVM's own gas and call-stack-depth limits stopped the unbounded recursion -- the unguarded version took a materially longer time to fail than a clean, intentional revert should, confirmed by timing both versions directly rather than assuming safety from a single passing test.

Root Cause: No explicit reentrancy guard existed on performNativeUpkeep or performCompatibleUpkeep. The contract's safety against this specific pattern depended entirely on the EVM's own resource limits eventually halting recursion, not on an intentional, cheap, immediate rejection.

Cost to Attack: $0 (a malicious client need only implement the reentrant call in its own performUpkeep; no external resources required).

Mitigation: An explicit nonReentrant guard was added to both performNativeUpkeep and performCompatibleUpkeep. Confirmed fixed by re-running the same unbounded reentrant-call test against the guarded contract: it now reverts immediately (a few seconds, the same as any normal transaction) rather than hanging for an extended period before eventually failing.

Status: FIXED, confirmed by a direct regression test comparing timing and outcome before and after the guard was added. This is the first finding in this whitepaper's audit history where the original unguarded behavior was confirmed unsafe specifically by demonstrating how long it took to fail, not only whether it failed.

AV-114 [LOWDOCUMENTED, FIXED]: Instant Withdrawal Could Strand a Keeper's Completed Work Unpaid

Attack: A client owner could call the registry's withdrawal function to drain their automation balance to zero in the same block a keeper's pending performUpkeep transaction would land, leaving that keeper unpaid for real off-chain monitoring work (watching for the condition, building and signing the transaction) already done before submission. Confirmed by direct test: requesting the withdrawal and immediately attempting the keeper's call in the same test run correctly showed the keeper's call failing with an insufficient-balance error after the owner's withdrawal completed instantly.

Root Cause: Withdrawal was instant -- no delay existed between a withdrawal request and funds leaving the contract, unlike the unbonding-period pattern already used elsewhere in this product family (EntropyAttestation.sol, LivenessGuard.sol).

Cost to Attack: $0 (requires only that the client owner choose to withdraw at an adversarial moment; no separate exploit needed). This is an economic griefing risk against keepers, not a fund-safety bug -- no one's money is stolen, but real off-chain work can go unpaid.

Mitigation: Replaced the instant withdrawal function with a queue-then-execute pattern: requestWithdrawal() queues an amount with a 1-hour delay, executeWithdrawal() (callable by anyone once the delay elapses) completes it, and cancelWithdrawal() lets the owner reverse a mistaken request. This is the same unbonding-period shape already used for EntropyAttestation.sol's and LivenessGuard.sol's own withdrawal paths, applied here for the first time to a client-owner-facing balance rather than a keeper-facing stake.

Status: FIXED, confirmed by a direct regression test showing a keeper's pending performUpkeep call now succeeds normally even after an owner has requested (but not yet completed) a withdrawal in the same window. This does not eliminate every timing strategy an owner could use against a keeper -- an owner can still queue a withdrawal well in advance of a known-upcoming deadline -- but it closes the instant, same-block version of the attack.

Round 11 Audit Summary

2 new findings (AV-113, AV-114), both found during RandProofAutomation.sol's own pre-deployment adversarial review and both fixed before any deployment, each with a direct regression test. 1 MEDIUM (AV-113, unbounded reentrant calls -- fixed with an explicit reentrancy guard, confirmed by timing comparison), 1 LOW (AV-114, instant withdrawal griefing against keepers -- fixed with a 1-hour withdrawal delay, the same unbonding pattern already used in EntropyAttestation.sol and LivenessGuard.sol). RandProofAutomation.sol now has 25 passing tests, including regression tests for both fixes, and is staged for the same testnet-deployment and external-audit path as the other two contracts in this product family. It remains true, and is disclosed as such, that RandProofAutomation.sol is not yet integrated with RandProofRNG, EntropyAttestation.sol, or LivenessGuard.sol, and has not had an external professional security audit.

29.16 Red Team Audit: Round 12: KeeperCoordinator.sol

Round 12 reviews KeeperCoordinator.sol (Section 19), the on-chain core every other contract in this product family depends on, before any deployment. This is the fourth contract to go through this specification-then-implementation-then-adversarial-review process, and the first round where building the test suite itself surfaced a genuine cryptographic design correction (Section 19.2.3) rather than only finding implementation bugs. 5 adversarial probes were run; all came back confirmed-safe except one disclosed LOW finding.

AV-115 [INFOCONFIRMED SAFE]: Signature Replay Across Different Events

Attack: Probed whether a valid t-of-n signature set for one eventId could be replayed against a different eventId to fulfill it without genuine keeper agreement on that second event's entropy.

Root Cause / Finding: eventId is part of the signed message (Section 19.2.2's signable message includes eventId explicitly). A signature set produced for one event recovers to the correct signer addresses only when verified against that exact event's message hash; submitting it against a different eventId produces a different message hash, and the recovered addresses no longer match the claimed signers.

Status: CONFIRMED SAFE by direct test: attempting this replay reverts.

AV-116 [INFOCONFIRMED SAFE]: Signature Replay Across Different Deployed Contract Instances

Attack: Probed whether a valid signature set for one deployed KeeperCoordinator instance could be replayed against a second, separately deployed instance for the identical eventId, drandValue, nistValue, and entropyBlock.

Root Cause / Finding: address(this) is part of the signed message. Signatures valid for one deployed instance recover to the correct signers only against that instance's own address; a different instance's address produces a different message hash.

Status: CONFIRMED SAFE by direct test: attempting this replay against a second, independently deployed instance reverts.

AV-117 [INFOCONFIRMED SAFE]: Double Finalization

Attack: Probed whether finalize() could be called a second time for an already-finalized event, which would risk a second fee distribution and a second client callback.

Root Cause / Finding: Request status moves to Finalized inside the first successful finalize() call, before the external callback and fee distribution complete (Checks-Effects-Interactions). A second call finds the status is no longer ChallengeWindowOpen and reverts.

Status: CONFIRMED SAFE by direct test.

AV-118 [INFOCONFIRMED SAFE]: Fee-Split Isolation From Non-Signing Registered Keepers

Attack: Probed whether a keeper registered on the contract, but who did not sign a specific event's fulfillment, could receive a share of that event's fee distribution by virtue of contributing to the global totalSignerStake figure used elsewhere in the fee math.

Root Cause / Finding: The hybrid fee-split model (Section 19.3) computes each signer's share using only the signers array recorded at fulfillment time for that specific event, not the full registered keeper set. A registered-but-non-signing keeper's stake is never read during that event's distribution.

Status: CONFIRMED SAFE by direct test: a registered keeper who did not sign the event received a pending withdrawal of exactly zero from that event's distribution.

AV-119 [LOWDOCUMENTED]: Dust-Level Fees Can Round Signer Shares to Zero

Attack: A sufficiently small request fee (tested directly at 10 wei) does not cause finalize() to revert, but integer division within the hybrid proportional/equal-split fee model can round one or more intermediate values to zero, meaning a signing keeper could in practice receive nothing for a dust-level request despite having done the real work of fetching entropy and signing.

Root Cause: Solidity integer division truncates; at very small fee amounts, the multiple intermediate divisions in the hybrid model (50% proportional / 50% equal split, each itself divided again per-signer) can compound to zero before reaching a signer's final share.

Cost to Attack: $0 (a natural occurrence at low fee amounts, not an attack requiring any special action).

Mitigation: Not a security hole -- no funds are misallocated or lost, they simply round down to zero rather than to a fractional amount no token system can represent anyway. The practical mitigation is operational, not a code change at this scale: document and enforce a sensible minimum request fee (the same minimum-fee convention already used elsewhere in this protocol's fee architecture, Section 29.1) high enough that a 3-way hybrid split never rounds a real signer's share to zero.

Status: DOCUMENTED, not yet enforced in code. A minimumFee check inside requestRandomness() would be a small, low-risk addition; not yet implemented, since the appropriate minimum depends on real fee-pricing decisions outside this contract's own scope.

Round 12 Audit Summary

5 findings (AV-115 through AV-119), 4 confirmed safe with no code change required, 1 LOW finding (AV-119, dust-fee rounding) documented with a recommended operational mitigation rather than a code fix, since the right minimum fee is a pricing decision outside this contract's scope. KeeperCoordinator.sol now has 26 passing tests including all 5 of these probes as permanent regression tests, and is staged for Base Sepolia testnet deployment alongside the other three contracts in this product family. It remains true, and is disclosed as such, that KeeperCoordinator.sol is not yet integrated with EntropyAttestation.sol, LivenessGuard.sol, or RandProofAutomation.sol, and has not had an external professional security audit.

29.17 Red Team Audit: Round 13: RandProofCertify.sol

Round 13 reviews RandProofCertify.sol (Section 9.1.4), the file/document/media attestation product, before any deployment. This is the fifth contract to go through this specification-then-implementation-then-adversarial-review process. Because this contract reuses EntropyAttestation.sol's already-audited 2-of-3 agreement, dispute, and bond-and-slash mechanism directly, this round focused specifically on the genuinely new surface area this contract adds -- string-based registration, certificate-ID derivation, and per-certificate state isolation -- rather than re-auditing logic already covered by AV-108 through AV-114. 4 adversarial probes were run; all came back confirmed-safe, with one cost-awareness note disclosed rather than treated as a finding.

AV-120 [INFOCONFIRMED SAFE]: Certificate ID Collision Resistance

Attack: Probed whether two certificates registered with an identical (publisher, fetchTarget, label) tuple could produce colliding certIds, allowing a later registration to silently overwrite an earlier certificate's record.

Root Cause / Finding: certId derivation includes certificateCount and block.timestamp in addition to the publisher/fetchTarget/label tuple, so two registrations that look identical from a publisher's perspective still produce distinct, non-colliding identifiers.

Status: CONFIRMED SAFE by direct test: two registrations with identical inputs produced distinct certIds.

AV-121 [INFODISCLOSED, NOT A SECURITY FINDING]: Long Labels Cost Proportionally More Gas

Attack: Probed whether an unusually long free-text label could cause unexpected (e.g. quadratic) gas cost, which would be a real DoS-adjacent concern distinct from ordinary string storage cost.

Root Cause / Finding: Measured directly: a 2,000-character label costs approximately 1.57 million gas for the registration call alone -- proportionally higher than a short label, but linear, not quadratic. This is the expected cost of Solidity string storage, not a vulnerability.

Status: DISCLOSED as an operational cost-awareness note in the contract's own documentation: publishers should keep labels reasonably short. No code change made or needed.

AV-122 [INFOCONFIRMED SAFE]: Per-Certificate State Isolation

Attack: Probed whether minority-pending dispute state could leak across unrelated certificates, which would risk one certificate's unresolved dispute incorrectly affecting another's resolution.

Root Cause / Finding: minorityPending and all other resolution state are stored per-certificate in the Certificate struct, keyed by certId; nothing is tracked at a contract-wide level that could cross-contaminate between certificates.

Status: CONFIRMED SAFE by direct test: a second, unrelated certificate showed no minority-pending state after a first certificate's dispute was created.

AV-123 [INFOCONFIRMED SAFE]: Cross-Contract Registry Independence

Attack: Probed whether a keeper slashed on RandProofCertify retains any privilege or stake on EntropyAttestation.sol, LivenessGuard.sol, RandProofAutomation.sol, or KeeperCoordinator.sol, which would indicate an unintended shared-state dependency across this product family's separate contracts.

Root Cause / Finding: Each contract in this product family maintains its own independent keeper registry, stake mapping, and slashing state by design -- none share storage. Confirmed directly by driving a keeper to a full slash on RandProofCertify specifically and verifying this state exists only on that contract.

Status: CONFIRMED SAFE by direct test. Worth stating plainly as a design consequence, not just a test result: a keeper wishing to operate across all five contracts in this product family must register and stake separately on each one. There is no shared identity or reputation system across them yet.

Round 13 Audit Summary

4 findings (AV-120 through AV-123), all confirmed safe with no code change required; one (AV-121) is a disclosed operational note rather than a security finding. RandProofCertify.sol now has 26 passing tests including all 4 of these probes as permanent regression tests, and is staged for Base Sepolia testnet deployment alongside the other four contracts in this product family. It remains true, and is disclosed as such, that RandProofCertify.sol is not yet integrated with any of the other four contracts, has not had an external professional security audit, and has no off-chain keeper automation yet for the fetch-and-hash step its design depends on.

29.18 Combined Audit Status and Mainnet Readiness Assessment (Rounds 1–13)

Across thirteen adversarial audit rounds plus targeted external review, 123 attack vectors have been identified and analyzed (AV-01 through AV-123), alongside the S-, C-, and K-series findings from earlier rounds. AV-112 (HIGH) was added directly to Section 23.1.5's consolidated committee-takeover analysis and is now implemented and tested as LivenessGuard.sol (22 passing tests, 6 adversarial probes, staged for Base Sepolia testnet deployment), a disjoint fallback committee and a non-fulfillment slashing counter that harden Genesis-phase censorship resistance specifically. AV-113 and AV-114 (Round 11, Section 29.15) were found and fixed during RandProofAutomation.sol's own pre-deployment review (Section 10) -- an unbounded reentrancy gap and an instant-withdrawal griefing risk against keepers, both closed with regression tests before any deployment. AV-115 through AV-119 (Round 12, Section 29.16) were found during KeeperCoordinator.sol's own pre-deployment review (Section 19) -- four confirmed-safe replay/isolation findings and one disclosed LOW finding (dust-fee rounding). KeeperCoordinator.sol is the on-chain core every other contract in this product family depends on, and building its test suite surfaced a genuine cryptographic design correction (Section 19.2.3: block.prevrandao cannot be pre-signed by keepers, since it is not predictable even one block in advance) -- the first time in this audit's history that test development itself produced a design fix rather than only an implementation fix. AV-120 through AV-123 (Round 13, Section 29.17) were found during RandProofCertify.sol's own pre-deployment review (Section 9.1.4) -- all four confirmed safe, with one (AV-121) a disclosed cost-awareness note rather than a security finding. RandProofCertify.sol is the fifth contract in this product family and the first built specifically by reusing an already-audited mechanism (EntropyAttestation.sol's 2-of-3 attestation) for a new payload (file/document/media hashes) rather than designing new attestation logic from scratch. All five contracts in this product family (EntropyAttestation.sol, LivenessGuard.sol, RandProofAutomation.sol, KeeperCoordinator.sol, RandProofCertify.sol) now follow the same specification-then-implementation-then-adversarial-review process before touching a testnet, and a first off-chain keeper reference implementation now exists (Section 19.4) with confirmed-live entropy source endpoints, though it does not yet implement real multi-keeper coordination. None of the five contracts call into any of the others yet -- each maintains its own independent keeper registry and stake, confirmed explicitly in Round 13 (AV-123) rather than merely assumed. As of this writing, three CRITICAL findings remain unresolved in code, AV-72 (single-founder physical coercion risk), AV-77 (keeper withdrawal drain via key compromise), and AV-84 (mobile biometric bypass via Android accessibility services), and this whitepaper does not claim otherwise. Round 10 is the first audit round in this document's history to review real, deployed-tested code (EntropyAttestation.sol) rather than a design specification; all 8 findings it and the preceding pre-deployment audit produced against that contract are closed with passing regression tests (31 total tests), and the contract is staged for Base Sepolia testnet deployment. This does not change the CRITICAL findings above or the overall mainnet readiness assessment: AV-72, AV-77, and AV-84 concern founder key custody, keeper withdrawal security, and mobile biometric handling respectively, none of which any of the five now-implemented contracts (EntropyAttestation.sol, LivenessGuard.sol, RandProofAutomation.sol, KeeperCoordinator.sol, RandProofCertify.sol) resolve, and none of which are claimed to be resolved by them. Per the priority classification below, RandProof Network is not ready for mainnet deployment until the P0 findings are resolved.

P0: must fix before any Genesis deployment (3 findings): AV-72 (3-of-5 treasury multisig plus distributing genesis keeper operation to 3+ independent parties), AV-77 (pre-registered withdrawal address, 24-hour timelock on address changes, daily withdrawal limit), AV-84 (Android BiometricPrompt with CryptoObject binding).

P1: must fix before Phase 2 mainnet / permissionless staking (9 findings): AV-59 (individual BLS partial signature verification on-chain), AV-65 (24-hour staking timelock against flash loan attacks), AV-78 (stake lock during challenge windows with slashing priority), AV-93 (reentrancy lock on the fulfillment callback), AV-94 (canonical Coordinator address registry), AV-97 (exact-amount USDC approvals), AV-98 (manual CCTP V2 treasury confirmation), AV-101 (hardware wallet support for high-stake keepers), AV-104 (governance parameter impact simulation).

P2: should fix before Phase 3 (the remaining MEDIUM-severity findings from Rounds 7–9) and P3: lower-priority hardening items (the remaining LOW-severity findings) are tracked individually above rather than summarized as a single bucket, since each carries its own attack description, root cause, and mitigation.

With the P0 and P1 fixes applied, RandProof Network would be positioned for a Genesis deployment under the federated trust model explicitly disclosed in Section 24.1: not under a claim that the federated model itself has been eliminated. The remaining P2 findings are intended for resolution on the Phase 2 timeline, before permissionless staking opens to the public.

Round 5 Adversarial Audit Summary

3 findings from external white-hat review (v3.9.5): AV-48 (selective non-fulfillment by a self-interested genesis keeper) is HIGH severity and DOCUMENTED rather than resolved, the liveness/refund safeguard limits damage but a commit-before-compute fix is still planned, not shipped. AV-49 (Wormhole/bridge treasury concentration) is RESOLVED by policy change: treasury settlement now uses native USDC where available via CCTP V2, and native chain assets (not bridged USDC) everywhere else, removing third-party bridge dependency from treasury flows entirely. AV-50 (single-founder key custody) is DOCUMENTED as an honest disclosure of current state: the Section 22.2 multisig is a Phase 2 target, not yet constituted. This whitepaper does not present target-state security claims as present-tense facts; phase-dependent claims are qualified throughout (see Section 26 for the entropy-source activation schedule corresponding to each phase).

13 attack vectors identified across 3 threat-actor scenarios. DDoS botnet: 4 vectors (AV-35 to AV-38), all resolved via port binding, connection limits, RPC redundancy, and fallback endpoints. Chainlink competitor: 3 vectors (AV-39 to AV-41), documented via stake concentration cap, FUD defense, and LoE contingency plan. Web3 hacker group: 6 vectors (AV-42 to AV-47), critical Docker Hub compromise (AV-43) resolved via Cosign signing + automatic verification, DNS hijacking (AV-47) resolved via TLS pinning + signature verification, GitHub compromise (AV-44) resolved via hardware 2FA + 2-of-3 branch protection.

Combined Audit Status (Round 1 + Round 2 + Round 3 + Round 4): 47 attack vectors analyzed across four adversarial audit rounds spanning generic attacks, edge cases, operational security, and threat-actor-specific scenarios (DDoS botnet, Chainlink competitor, Web3 hacker group). 0 CRITICAL unresolved. 0 HIGH unresolved. 32 resolved with code fixes, 14 documented with mitigations, 1 confirmed no-issue. The protocol is hardened against: (1) DDoS at the network, RPC, and entropy-source layers, (2) well-funded competitor Sybil infiltration via 15% stake concentration cap, (3) supply chain attacks via Cosign Docker signing, GPG commit signing, and npm provenance, (4) social engineering via typosquat registration and official channel verification, (5) DNS/BGP hijacking via TLS pinning and cryptographic signature verification, (6) all 34 previously identified attack vectors from Rounds 1-3. No randomness protocol in Web3 has undergone this depth of adversarial security review before mainnet deployment.

29.19 Red Team Audit: Round 14: v0.55 New Product Designs (Sentinel, Forge, Oracle, Identity, Audit, Custody Proof)

Round 14 is different in kind from Rounds 1 through 13. The prior rounds attacked implemented, tested code (EntropyAttestation.sol, KeeperCoordinator.sol, RandProofAutomation.sol, LivenessGuard.sol, RandProofCertify.sol). Round 14 attacks the six product designs introduced in Sections 12 through 17, none of which is yet implemented, deployed, or externally audited, as each section’s own Honest Status subsection states plainly. This round therefore makes no claim that these products are secure; there is no code to secure. It is an adversarial design review: each specified architecture was attacked as written, and the weaknesses in the designs, plus one document-integrity defect, are recorded here in the standard AV format as AV-124 through AV-136. Catching these at design stage is precisely when they are cheapest to fix.

13 findings: 0 CRITICAL, 3 HIGH, 6 MEDIUM, 3 LOW, 1 INFO. No finding identifies broken cryptography; the HIGH findings are gaps in stated guarantees and one document-integrity defect, all resolvable with specification changes rather than redesign. The recurring Honest Status and What-X-Does-Not-Claim discipline throughout Sections 12-17 was assessed as a genuine security asset, not a formality: it pre-empts the overclaiming that is itself a common source of downstream security incidents.

AV-124 [HIGHRESOLVED in v0.55]: Document-wide duplicate subsection numbering. After Sections 12-17 were inserted and later sections renumbered, 151 subsection headers across Sections 18-31 retained their pre-insertion numbers, producing duplicate identifiers (two 12.1s, two 13.4s, and so on) throughout the back half of the document. For a document whose credibility rests on precision, this was a material trust defect. Fixed in v0.55 by a full subsection-renumbering pass; every subsection header now matches its parent section, and four pre-existing numbering inconsistencies inherited from earlier versions were corrected in the same pass. Verified zero remaining header mismatches at v0.55. v0.57 amendment (Round 15, AV-137): that verification covered section headers only -- in-body cross-references retained pre-renumbering targets and were corrected document-wide in v0.57.

AV-125 [HIGH]: Forge Native (Section 13.5) returns the primary compute agent’s output to the requester before the fidelity certificate is issued, optimizing for latency, but does not specify what a requester may safely do with a pre-certificate output or require an in-band uncertified-status signal. A malicious agent could return a manipulated result that the requester acts on irreversibly before the challenge window catches and slashes the agent. This re-introduces, in Forge, the exact irreversible-action risk that Sentinel (Section 12) exists to prevent. Recommended fix: an explicit UNCERTIFIED status flag on pre-certificate outputs, a Does-Not-Claim note that acting on them is a requester-accepted risk, and a wait-for-certificate mode for high-value use. Disclosed for resolution in a future revision.

AV-126 [HIGH]: RandProof Oracle (Sections 14.2-14.5) specifies a per-fetch max_latency_ms but no in-band staleness or heartbeat guarantee for continuous/subscription feeds, the classic oracle staleness problem that has caused real DeFi liquidation losses. A consuming protocol cannot tell from the feed alone whether the last published value is still fresh. Since Oracle explicitly targets DeFi price feeds against incumbent oracle networks, which all ship a heartbeat and updatedAt timestamp, this is a material gap. Recommended fix: a required consumer-readable updatedAt timestamp and per-feed heartbeat/deviation-threshold spec, plus a Does-Not-Claim note that consumers must check freshness. Disclosed for resolution in a future revision.

AV-127 [MEDIUM]: Sentinel’s Execute-phase commit-reveal (Section 12.3) does not specify a reveal timeout, a penalty for commit-without-reveal, or a resolution path for a stalled reveal round, leaving it exposed to the classic last-revealer withholding problem, the same attack shape already documented against the randomness path elsewhere in this document. Recommended fix: reveal-phase timeout, bond forfeiture for commit-without-reveal, and a defined stall-resolution path reusing the existing FULFILLMENT_TIMEOUT/cancelRequest pattern. Disclosed for resolution in a future revision.

AV-128 [MEDIUM]: Oracle continuous-value consensus (Sections 14.3-14.4) accepts reveals within a configured tolerance band but does not specify how the consensus value is computed within that band, a minimum keeper count for band-based feeds, or a maximum band width. On a thin feed or small keeper set, a coordinated minority could pull the accepted value toward a favorable band edge without triggering the exact-match fraud signal. Recommended fix: specify median (not mean) computation, a minimum keeper count, and a maximum band width relative to feed value, with explicit disclosure that band feeds carry weaker manipulation resistance than exact-match feeds. Disclosed for resolution in a future revision.

AV-129 [MEDIUM]: RandProof Identity (Section 15) defines no expiry or freshness window on an IdentityCertificate. A point-in-time result such as sanctions_clear may no longer be true when a consumer later relies on a cached score. Recommended fix: a required validUntil/attested-at field on every IdentityCertificate, a per-claim_type recommended freshness window, and a Does-Not-Claim item stating a certificate attests a claim only as of its timestamp. Disclosed for resolution in a future revision.

AV-130 [MEDIUM]: Forge (Section 13.4) correctly insists PoRC provenance certificates and fidelity certificates must never be interchangeable, but states this as a requirement rather than a mechanism: no certificate-schema-level enforcement (distinct type, distinct contract, distinct verification entrypoint) is specified that would make misrepresentation impossible rather than merely discouraged. Recommended fix: specify PoRC and fidelity certificates as distinct on-chain types with distinct verification functions, so a consumer querying for fidelity cannot receive a provenance certificate by accident or misuse. Disclosed for resolution in a future revision.

AV-131 [MEDIUM]: RandProof Audit (Section 16.2) makes a consensus-confirmed violation a permanent part of a protocol’s audit history but specifies no path to contest a false-positive violation arising from a mis-specified invariant, a transient state read, or a keeper-consensus error. A permanent, unfixable false violation mark against a solvent protocol is a reputational griefing vector. Recommended fix: preserve record permanence but add an on-chain dispute/annotation mechanism whereby a contested violation can be marked disputed and resolved, with the resolution also permanent. Disclosed for resolution in a future revision.

AV-132 [MEDIUMDISCLOSED]: Custody Proof’s cross-chain canonical registry (Section 17.2, Phase 4) is, by the document’s own admission (Section 17.5, echoing Section 9), the most valuable and least-built component, and is structurally a centralization point: whoever controls or corrupts it can permit the cross-chain double-backing the product exists to prevent. This finding does not fault the disclosure, which correctly flags the component as requiring its own dedicated adversarial audit before deployment; it records that the current mitigation is do-not-ship-until-audited, which is appropriate but must not be dropped when this moves from roadmap to build. When specified, the registry needs its own multi-chain-consensus trust model documented and audited as a first-class component.

AV-133 [LOW]: Sentinel’s executeTask() (Sections 12.3, 12.6) performs an external call into a client-registered target_selector but the design does not address re-entrancy into Sentinel itself during that call. Standard, well-understood control; recorded so it is not forgotten at implementation. Recommended fix: apply checks-effects-interactions and a re-entrancy guard around executeTask(), with a design note added now. Disclosed for resolution at implementation.

AV-134 [LOW]: RandProof Identity (Section 15.2) references a confidence score where the claim type supports gradation but defines no scale, derivation, or meaning, implying a precision the underlying weak signals do not support and inviting inconsistent interpretation across consumers. Recommended fix: either define the score precisely (inputs, range, meaning) or replace it with a small set of named tiers. Disclosed for resolution in a future revision.

AV-135 [LOWRESOLVED in v0.55]: Typo in the Section 23 threat matrix (formerly 16.4): the word holding was misspelled in the phrase describing a keeper falsely reporting a holding status when peers report a violation. Trivial in isolation, but logged rather than silently corrected because in a security table such details erode reader confidence. Corrected in v0.55.

AV-136 [INFORESOLVED in v0.55]: All of Sections 12-17 carry the [Layer 1: Core] tag, identical to shipped, tested products, with maturity (design-only vs implemented) disclosed only in each section’s closing Honest Status paragraph rather than at a glance. A skimming reader could mistake a design sketch for shipped infrastructure. Recommendation: add a lightweight maturity marker alongside the layer tag (for example, Design Stage vs Implemented), so status is visible without reading to the end of each section. Recorded as a recommendation; strengthens rather than weakens the document’s honesty posture.

Round 14 Audit Summary

13 findings (AV-124 through AV-136): 0 CRITICAL, 3 HIGH, 6 MEDIUM, 3 LOW, 1 INFO. Three findings are resolved in v0.55 itself (AV-124 subsection renumbering, AV-135 typo, and AV-136 maturity tags); the remainder are disclosed for resolution in future revisions or at implementation, consistent with the fact that the underlying products are design-stage. Cumulative across all rounds: 136 attack vectors analyzed across 14 adversarial review rounds. This round makes no claim that Sections 12-17 are secure; those products are not yet implemented. It claims only that the designs were attacked as written and these specific weaknesses were found, recorded, and, where possible, resolved. The correct next step for the already-implemented contracts remains an external professional security audit and cross-contract testnet integration, not further internal review.

29.20 Red Team Audit: Round 15: v0.56 Document Integrity and Claim-Consistency Review

Round 15 attacks the v0.56 document as written, the state a reader, investor, or external auditor would receive it in, rather than contract code (Rounds 10-13) or product designs (Round 14). Its lens is the one AV-124 introduced: for a document whose credibility rests on precision and honest disclosure, internal inconsistency is itself a security-relevant defect. 12 findings were recorded (AV-137 through AV-148): 0 CRITICAL, 4 HIGH, 6 MEDIUM, 2 LOW. All 12 are resolved in v0.57 itself; the dominant failure mode was edit residue, statements true in earlier versions surviving into v0.56 alongside their corrections.

AV-137 [HIGHRESOLVED in v0.57]: Systemic stale cross-references. The v0.55 renumbering pass (AV-124) corrected section headers but not in-body cross-references: roughly 39 references throughout the document retained pre-renumbering targets, 17 instances of "Section 31.1" pointing at the mobile app instead of the Section 24.1 genesis trust model, 4 instances of "Section 30.1.5" pointing at the runbook instead of Section 23.1.5, references to "Section 30.13-30.17" instead of 29.13-29.17, references to "Section 26.1-26.4" instead of 19.1-19.4, several runbook self-references off by one section, and treasury-multisig references to "Section 29.2" instead of 22.2. This made AV-124's recorded statement "verified zero remaining mismatches" false in v0.56: inside the audit section itself. Fixed in v0.57 by a full cross-reference remapping pass with per-reference context verification; AV-124's status text is amended rather than silently rewritten, preserving the audit trail's own history.

AV-138 [HIGHRESOLVED in v0.57]: Direct factual contradiction on KeeperCoordinator.sol. Section 23.1.5 stated the contract "does not exist as code" while Sections 19.0, 29.16, and 29.18 describe it as a tested MVP with 26 passing tests. The 23.1.5 text was stale pre-Round-12 language; corrected to match Round 12 reality.

AV-139 [HIGHRESOLVED in v0.57]: HotBits residue contradicted the document's own entropy policy, and instructed operators to violate it. Although Source 9 and the AV-54 redistribution rule state that HotBits is retired and no acceptable ANU QRNG fallback exists, three artifacts survived: the Section 3.3 aggregation formula still used the variable name hotbitsQRNG; the Section 30.4 .env reference shipped HOTBITS_FALLBACK_ENDPOINT and HOTBITS_API_KEY pointing at the retired fourmilab service; and Section 30.10.2 troubleshooting told operators to verify the fallback endpoint was set. A node operator following the runbook as written would have wired a disavowed, uncertified source into live keeper behavior. All three corrected in v0.57: variable renamed to anuQRNG, both environment variables removed with an explanatory comment, and the troubleshooting guidance rewritten to point at automatic weight redistribution.

AV-140 [HIGHRESOLVED in v0.57]: Absolute security guarantee in Section 3.3 overstated the aggregation property and contradicted the document's own disclosures. The claim that compromising the output "requires simultaneously controlling all fifteen entropy sources" conflicted with the Source 12 trust-root disclosure (one organization controls two sources), the Sources 13-15 genesis disclosure, and the phased rollout, and overstated what hash aggregation provides, since a last-mover controlling a single input while observing the others gains grinding leverage; the commit-before-observe ordering, attestation, challenge window, and slashing are the actual mitigations. Replaced with the Phase-4-qualified phrasing already used in Section 23.1.5, with the single-source grinding vector and its mitigations named explicitly. The unverifiable superlative ("more entropy sources than any other protocol in the world") was softened to match the Conclusion's existing discipline.

AV-141 [MEDIUMRESOLVED in v0.57]: The Abstract claimed "seven entropy domains" while listing six. Protocol-Native added to the list.

AV-142 [MEDIUMRESOLVED in v0.57]: Subsection numbering gaps survived the AV-124 pass: Section 7 jumped to 7.2 with no 7.1; Section 8 contained 8.1, 8.3, 8.7; Section 29 jumps from 29.6 to 29.11. Sections 7 and 8 renumbered contiguously (7.1; 8.1-8.3) with all in-text references updated; the 29.7-29.10 gap is retained deliberately for Round-numbering citation stability and is now documented by an editorial note preceding Section 29.11.

AV-143 [MEDIUMRESOLVED in v0.57]: The Section 24.1 genesis disclosure itself overclaimed, stating randomness integrity "is guaranteed by the 15 independent external entropy sources", only twelve sources are external, three are protocol-native and founder-controlled at genesis, and fewer than twelve external sources are live at the current phase. Rewritten to state exactly which inputs are and are not independent of the genesis keeper set.

AV-144 [MEDIUMRESOLVED in v0.57]: The roadmap switched counting conventions mid-table: Phase 1 declared Sources 13-15 live from Genesis, yet Phases 2 and 3 counted external sources only ("7 sources", "9 sources") before Phase 4 counted everything ("15 sources total"). Interim counts now labeled explicitly as external-source counts with totals alongside.

AV-145 [MEDIUMRESOLVED in v0.57]: The Polkadot minimum stake (0.5 DOT, ~$3) broke the ~$20-60 economic floor assumed by the Section 23.2.2 Sybil analysis, a rational attacker registers on the cheapest chain, making the effective 1,000-node Sybil cost $3,000 rather than the stated $20,000-60,000. Finding K-03 had already recommended 5 DOT ($30); v0.57 applies that recommendation to the Section 21.1 table, marks K-03 resolved, and adds an explicit per-chain USD-floor calibration note.

AV-146 [MEDIUMRESOLVED in v0.57]: The Section 4 comparison table stated Phase 4 targets and non-MVP properties in present tense: fifteen sources and full redundancy as current facts, and "no admin key, immutable" despite the implemented contracts carrying a timelocked assigner role and Section 19.2.1 being titled "Four Entropy Sources, Not Fifteen." Phase 4 qualifiers added to the entropy rows, the admin-key row restated precisely, and the public-beacon count corrected from three to four (drand Quicknet).

AV-147 [LOWRESOLVED in v0.57]: Claim-hygiene items: the Section 21.1 opening listed five sources inside a "fifteen sources" sentence with no ellipsis (now marked "and ten more"); and Finding C-02's recommended timestamp hardening was never applied to the Section 3.3 canonical formula, timeEntropy now hashes the timestamp with block number and prior block hash, and C-02 is marked resolved.

AV-148 [LOWRESOLVED in v0.57]: The Section 4 competitor figures carried no as-of date or source, a credibility and accuracy exposure disproportionate to their marketing value. An as-of note now follows the table, and it should be re-verified against current Chainlink documentation at every version bump.

Round 15 Audit Summary: 12 findings (AV-137 through AV-148): 0 CRITICAL, 4 HIGH, 6 MEDIUM, 2 LOW, all 12 resolved in v0.57. Cumulative across all rounds: 148 attack vectors analyzed across 15 adversarial review rounds. This round changes nothing about mainnet readiness: AV-72, AV-77, and AV-84 remain the open P0 CRITICALs, and the Section 29.18 assessment, not ready for mainnet until they are resolved, stands. Process change adopted with this round: because manual review has demonstrably stopped catching edit residue at the document's current length, every future version bump runs a mechanical consistency pass before release, automated cross-reference target verification, subsection-continuity checking, and a grep list of retired terms (HotBits, "does not exist as code", superseded version strings). The correct next step for the implemented contracts remains an external professional security audit, not further internal review.

On this page