name: tn-threat-model description: | Generate security threat model documentation for telcoin-network components. Trigger on: "threat model", "attack surface", "security architecture", "adversary model", "security doc", "audit prep"
Threat Model Generator
Generate structured security threat model documentation for the telcoin-network repo -- a Rust blockchain node combining Narwhal/Bullshark DAG-based BFT consensus with EVM execution via Reth.
Project Context
Telcoin Network is a permissioned-set (staked validator) blockchain with a DAG-based BFT consensus layer (Narwhal/Bullshark) and Reth-based EVM execution. The threat model skill needs to understand the adversary model and key invariants that constrain what attacks are possible:
- Byzantine fault tolerance: tolerates f < n/3 faulty validators.
- Quorum threshold: 2f+1 (calculated as
2*n/3 + 1). Validity threshold: f+1 (calculated asceil(n/3)). - Equal voting power: all validators have
EQUAL_VOTING_POWER = 1— no stake-weighted voting. - Gossipsub topic access: only current committee members may publish on consensus topics.
- System call isolation:
SYSTEM_ADDRESS(0xfffe...fe) is not callable by external accounts. - TEL precompile governance: restricted to
GOVERNANCE_SAFE_ADDRESS.
Process
When asked to generate a threat model, follow these phases:
Phase 1: Scope
Determine which component or subsystem to model. Ask the user if unclear. Options include:
- Full system (high-level)
- Consensus (primary DAG, certificate aggregation, Bullshark ordering)
- Networking (libp2p, gossipsub, peer management, Kademlia)
- Execution (EVM, precompiles, system calls, transaction pool)
- Synchronization (epoch chain, consensus chain, state sync)
- RPC (external API surface)
- A specific crate (e.g.,
crates/network-libp2p/,crates/consensus/primary/)
Phase 2: Map Trust Boundaries and Entry Points
Identify all points where untrusted data enters the system. Key entry points in this codebase:
- Gossipsub messages (
crates/network-libp2p/src/consensus.rs) -- certificates, batch announcements, consensus output results. Only committee members should publish. Validated via BLS signature before propagation. - Request-response messages (
crates/consensus/primary/src/network/) -- vote requests, missing certificate requests, consensus output requests, epoch record requests. Handled byRequestHandlerinhandler.rs. - RPC endpoints (
crates/execution/tn-rpc/) --tn_latestConsensusHeader,tn_genesis,tn_epochRecord,tn_epochRecordByHash. Plus standard Reth JSON-RPC (eth, debug, trace). - Transaction pool (
crates/tn-reth/src/txn_pool.rs) -- user-submitted transactions entering the mempool. - Worker batch broadcasts -- batches of transactions from workers to primaries.
- Kademlia DHT --
NodeRecordpublication for peer discovery. Committee validators publish records keyed by BLS public key. - Stream-based sync (
StreamBehaviorin the libp2p network) -- bulk data transfer for state sync.
For each entry point, read the relevant handler code and document:
- What data is received
- What validation occurs before processing
- What happens on validation failure (penalty, disconnect, ignore)
- Whether the handler is rate-limited or bounded
Phase 3: Identify Adversary Model and Capabilities
Document the adversary model derived from the protocol's BFT assumptions:
- Byzantine validators: Up to f = floor((n-1)/3) validators may be arbitrarily malicious. They can equivocate (sign conflicting messages), withhold messages, or send malformed data.
- Network adversary: Can delay, reorder, or drop messages between honest nodes. Cannot forge BLS signatures.
- External attacker: No committee membership. Can send transactions via RPC, attempt to connect as a peer, submit malformed requests.
- Compromised key: A validator's BLS keypair is compromised. Attacker can sign valid messages as that validator.
Search for specific adversary handling:
- Equivocation detection:
auth_last_votemap inRequestHandlertracks last vote per authority to detect equivocation early. - Behind-consensus detection:
behind_consensus()in handler detects when a node is too far behind and switches to catchup mode. - Committee verification:
get_committee()validates messages against the correct epoch's committee.
Phase 4: Enumerate Attack Vectors per Component
For each component in scope, enumerate concrete attacks. Use subagents to explore code in parallel. Key vectors to investigate:
Consensus attacks:
- Certificate forgery (forge BLS aggregate signatures)
- Equivocation (sign conflicting headers for the same round)
- Parent withholding (withhold certificates to slow DAG progress)
- Round manipulation (propose headers with inflated round numbers)
- GC window exploitation (exploit the garbage collection depth boundary)
Networking attacks:
- Message flooding (overwhelm gossipsub with valid-looking messages)
- Gossipsub amplification (exploit mesh propagation)
- Peer score gaming (manipulate scoring to avoid bans while being malicious)
- Sybil via Kademlia (flood DHT with fake node records)
- Eclipse attack (isolate a validator from honest peers)
Execution attacks:
- Malformed batch injection (batches with invalid transactions)
- System call spoofing (attempt to call system-only functions from external accounts)
- TEL precompile exploits (governance function access, timelock bypass if
faucetfeature leaks to mainnet) - Gas cost undercharging (some precompile operations are undercharged vs EVM equivalent -- see TEL precompile README gas tables)
- Transaction pool resource exhaustion
Sync attacks:
- Epoch record forgery (provide fake epoch records during sync)
- Consensus header manipulation (omit or reorder consensus headers)
- Stale committee injection (serve outdated committee data to syncing nodes)
Phase 5: Catalog Existing Security Controls
Search the codebase for these control categories and document what exists:
- BLS signature verification:
verify_cert(),verify_signature(),verify_secure()incrates/types/src/crypto/. Certificates require quorum (2f+1) valid BLS signatures. Aggregate signature verification viaBlsAggregateSignature. - Peer banning and scoring:
PeerManagerincrates/network-libp2p/src/peers/. Penalty levels:Mild(50 before ban),10 before ban),Medium(Severe(~5 before ban),Fatal(immediate ban). Score decay over time. Temporary ban cache prevents immediate reconnection. - System call access control:
SYSTEM_ADDRESSincrates/tn-reth/src/system_calls.rs. EVM handler checks caller is system address.SystemCallable.solin contracts enforces on-chain. - TEL precompile guards: Governance-only functions check
GOVERNANCE_SAFE_ADDRESS. Timelock on mainnet mints (7-day). Signature malleability rejection inpermit. Double-claim prevention. - Gossipsub message validation: Source peer must be a staked validator. Invalid messages trigger
PenaltyviaPeerManager. Topic validation ensures messages arrive on correct topics. - Equivocation detection:
auth_last_votemap inRequestHandlercaches last vote per authority with epoch, round, and header digest. - Network behavior ordering:
TNBehaviorstruct placespeer_managerfirst so banned-peer connection denials fire before other behaviors register the connection. - Epoch chain verification: Syncing nodes verify each epoch record's BLS certificate (2/3+1 signatures) and chain the records via parent hashes. See
SYNC.md.
Phase 6: Identify Gaps
Search for known weakness patterns and flag them:
- HashMap in consensus paths:
HashMapis used in several consensus-critical data structures (e.g.,RequestHandlerfields,batch_fetcher.rs). HashMaps use SipHash which is DoS-resistant, but ordering non-determinism could cause subtle consensus divergence if iteration order matters. Grepcrates/consensus/forHashMapusage. - Unbounded channels: Search for
unbounded_channelin consensus paths (crates/consensus/primary/src/certificate_fetcher.rs,crates/consensus/primary/src/certifier.rs). Unbounded channels can be exploited for memory exhaustion if a malicious peer floods the receiver. - Gas undercharging in precompile: The TEL precompile README documents that
approve,mint(mainnet),burn, andgrantMintRoleare undercharged relative to worst-case EVM cost. This means these operations are subsidized, which could be exploited for gas-based DoS. - Peer reputation metric gaps: Check if peer scoring captures all penalty-worthy behaviors. Look for error paths in network handlers that do NOT assess a penalty.
- Rate limiting on RPC: Check whether the
tn_*RPC endpoints have rate limiting or request size bounds. - Kademlia record validation: Verify that DHT records are validated (BLS key ownership) before being accepted.
- Total supply accounting drift: TEL
totalSupplydoes not account for native balance changes outside the precompile (gas fees, coinbase rewards). Off-chain indexers must reconcile.
Phase 7: Generate the Threat Model Document
Produce the final document using the output format below. Write it to a location agreed with the user (e.g., docs/threat-model.md or tasks/threat-model-{component}.md).
Output Format
The generated threat model document MUST follow this structure:
# Threat Model: {Component/Scope}
Generated: {date}
Scope: {what was analyzed}
Commit: {git short hash}
## System Overview
Brief architectural description of the component being modeled.
Include a data flow summary showing how messages/data enter and exit the component.
## Trust Boundaries
| Boundary | Inside (Trusted) | Outside (Untrusted) | Crossing Mechanism |
|----------|-------------------|---------------------|--------------------|
| ... | ... | ... | ... |
## Adversary Model
- **Byzantine validators (f < n/3)**: capabilities and constraints
- **Network adversary**: what they can and cannot do
- **External attacker**: no committee keys, limited to RPC/P2P connection
- **Key compromise**: single validator key leaked
## Attack Surface
### {Component 1}
| # | Attack Vector | Entry Point | Preconditions | Impact | Likelihood | Severity |
|---|---------------|-------------|---------------|--------|------------|----------|
| 1 | ... | ... | ... | ... | ... | ... |
### {Component 2}
...
## Security Properties
What MUST hold for the system to be correct:
- [ ] Property 1 (e.g., "No certificate accepted without 2f+1 valid BLS signatures")
- [ ] Property 2
- ...
## Controls Inventory
| Control | Location | Protects Against | Status |
|---------|----------|------------------|--------|
| ... | ... | ... | ... |
## Gaps and Recommendations
| # | Gap | Risk | Recommendation | Priority |
|---|-----|------|----------------|----------|
| 1 | ... | ... | ... | ... |
Rules
- ALWAYS read the actual source code before documenting a control or gap. Do not assume based on naming alone.
- Use subagents to explore multiple crates in parallel when mapping attack surfaces.
- When documenting an attack vector, include the specific code path an attacker would target (file + function).
- For each gap, verify it is actually present by reading the code. Do not flag theoretical issues without evidence.
- Severity ratings use: Critical (consensus break / fund loss), High (network partition / DoS), Medium (degraded performance / information leak), Low (minor / requires unlikely preconditions).
- Likelihood ratings use: High (exploitable by external attacker with no special access), Medium (requires compromised validator or sustained effort), Low (requires multiple compromised validators or race conditions).
- Always check the current git commit hash and include it in the output for reproducibility.
- Cross-reference findings with
SECURITY.mdfor responsible disclosure context. - Do not generate a threat model for out-of-scope items (third-party dApps, dependency vulnerabilities, social engineering). See
SECURITY.mdscope table. - When the user asks for "audit prep", generate the full-system threat model and additionally list the top 10 highest-priority items a security auditor should focus on.
- Write the threat model document to the location the user specifies. Default to
tasks/threat-model-{scope}.mdif no location is given. - After generating, ask the user if they want to drill deeper into any specific component or attack vector.