ability-analysis
Trigger Pattern Always (Aptos Move) - foundational security check - Inject Into Breadth…
L1 trigger - audits fork-choice rule implementation (LMD-GHOST, Tendermint locking, Nakamoto longest-chain) for equivocation handling, slot-vs-block reasoning, duplicate block handling, and chain reorg correctness.
$ npx -y skills add PlamenTSV/plamen --skill fork-choice-audit --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/fork-choice-auditContext preview
The summary Claude sees to decide when to auto-load this skill.
L1 trigger - audits fork-choice rule implementation (LMD-GHOST, Tendermint locking, Nakamoto longest-chain) for equivocation handling, slot-vs-block reasoning, duplicate block handling, and chain reorg correctness.
name: "fork-choice-audit" description: "L1 trigger - audits fork-choice rule implementation (LMD-GHOST, Tendermint locking, Nakamoto longest-chain) for equivocation handling, slot-vs-block reasoning, duplicate block handling, and chain reorg correctness."
> **L1 trigger**: `L1_PATTERN=true` AND (`fork_choice/` OR `ghost/` OR `lmd/` OR `consensus/tendermint/` OR `fork.rs` OR `choice.rs` detected in recon subsystem map) > **Inject Into**: `depth-consensus-invariant` > **Language**: Go and Rust > **Finding prefix**: `[FC-N]` > **Status**: v0.1 draft, Round 4 exemplars pending
Recon identifies a fork-choice module. This skill applies whether the protocol uses LMD-GHOST (Ethereum beacon chain), longest-chain (Bitcoin, pre-merge Ethereum), Tendermint locking (Cosmos), or a custom fork-choice rule.
Before auditing, determine which rule is implemented. Extract from spec docs and code:
| Rule | Signature | Key invariants | |---|---|---| | **LMD-GHOST** | "latest message driven — greedy heaviest observed subtree" | Each validator's latest attestation contributes to a subtree weight; choose heaviest | | **Casper FFG + LMD-GHOST** (Ethereum) | LMD-GHOST bounded by finalized checkpoints | Never revert past justified/finalized checkpoint | | **Tendermint BFT** | Round-based, locking on 2/3+ prevotes | Locked validator cannot vote for conflicting proposal in same round | | **Nakamoto longest-chain** | Heaviest accumulated work | Chain with most work wins; stale blocks discarded | | **HotStuff / Aptos / Sui** | 3-phase: prepare, precommit, commit | No two conflicting QCs at the same view |
Write the identified rule into the finding header so reviewers know which invariants apply.
**Check**: Enumerate every call site of `find_head()` / `get_head()`. For each, verify the return value is bounded by the latest finalized checkpoint.
**Check**: Follow the `lock_value`, `lock_round`, `valid_value`, `valid_round` state variables. Verify every `set_lock` call is guarded by the 2/3 check.
Equivocation = a validator signing two conflicting attestations. Fork choice must:
1. **Detect** equivocation via slashing conditions (double vote, surround vote, double proposal) 2. **Preserve** both conflicting signatures as evidence 3. **Not crash** or hang when two conflicting messages arrive in close proximity 4. **Not double-count** the equivocator's weight — their vote should NOT contribute to fork-choice weight after equivocation is detected
**Check**:
**Known exemplar class**: Cosmos / Tendermint "Denial of Validators" attacks — multiple historical bugs where equivocation detection could itself be exploited to halt the chain.
Tag: `[EQUIVOC:{loc}:{handling}]`
When fork choice selects a new head, the node must reorg: revert state from the old head back to the common ancestor, then apply blocks from the common ancestor to the new head.
**Check**: 1. Enumerate all state that must be rolled back on reorg: account balances, nonces, receipts, logs, fork-choice's own caches 2. For each state category, verify the reorg path touches it 3. Look for **side-channel state** that does NOT roll back: metrics, logs flushed to disk, cached RPC responses, indexer state 4. On reorg, is any background task (indexer, RPC subscription, metrics) left in an inconsistent state?
Tag: `[REORG-GAP:{state-category}]`
For every helper that returns blocks to apply during a reorg (`get_fork_blocks`, `fork_blocks`, `blocks_to_apply`, `ancestor_path`, `rollback_path`):
1. Determine the expected order: ancestor → child → ... → new head for forward application, or old head → ... → ancestor for rollback. 2. Inspect whether the implementation collects by walking parent pointers from head to ancestor and forgets to reverse the list. 3. Check all consumers: if a function expects forward order but receives reverse-chro
Autonomous Web3 security auditor for Claude Code and OpenAI Codex CLI. Orchestrates 18-100 AI agents across 40+ phases to produce audit reports with verified PoC exploits — for smart contracts and L1 node-client infrastructure.
Repo: PlamenTSV/plamen
Trigger Pattern Always (Aptos Move) - foundational security check - Inject Into Breadth…
Trigger Pattern Always (Aptos Move) - Move VM aborts on shift = bit width - Inject Into…
Trigger Protocol has privileged roles (admin, operator, governance, resource account owner) -…
Trigger EXTERNAL_LIB flag detected (protocol uses third-party Move dependencies) - Used by…
Trigger Pattern MONETARY_PARAMETER flag (required) - Inject Into Breadth agents (merged via…