Skip to content

Cross-Contract Reentrancy Detection via Multi-Hop Call-Graph Traversal (CP-121) #66

Description

@Nanle-code

Problem Statement

ChainProof's existing reentrancy detectors (CP-107, swc107-reentrancy-v2.ts) analyze external-call-before-state-update patterns within a single function/contract. The multi-file import-graph and call-graph resolution built for the "Multi-file contract analysis with inheritance and import graph resolution" work gives ChainProof the infrastructure to see across contract boundaries, but no rule currently uses it to detect cross-contract reentrancy: the case where Contract A calls into Contract B, which calls back into Contract A (directly, or via a third Contract C), re-entering a function whose state hasn't been finalized yet. This is precisely the pattern behind several real-world exploits in vault/strategy architectures and is invisible to single-function analysis.

Proposed Solution

Implement a new detector, CP-121 (multi-hop cross-contract reentrancy), built on top of the existing rules/call-graph.ts infrastructure:

  • Traverse the resolved call graph across the full set of scanned and imported contracts to find call chains of length two or more (A.f() → B.g() → A.h(), or longer) where the re-entered contract (A) has unfinalized state changes pending between the initial external call and the point of re-entry.
  • Distinguish chains that are protected by a consistent reentrancy guard (e.g., a nonReentrant-style modifier applied across the whole chain, or checks-effects-interactions correctly applied at every hop) from genuinely exploitable chains.
  • Support a configurable traversal depth (default 3 hops) with a hard cap to keep analysis time bounded on large protocols, and short-circuit cycles that don't involve unfinalized state.
  • Findings must reference the full call chain (each contract/function/line in the path), not just the terminal re-entrant call, so the report is actionable.
  • Integrate with the existing severity model (critical, given this class of bug is typically fund-draining) and with the Slither merge/deduplication logic so a Slither-detected same-chain finding doesn't produce a duplicate.

Technical Scope

  • New packages/core/src/rules/cp121-cross-contract-reentrancy.ts implementing the traversal and detection logic against the existing CallGraph type from rules/call-graph.ts.
  • Extend rules/rule-context.ts if needed so the rule has access to the full multi-file call graph, not just the current file's AST.
  • Register the rule in scanner.ts and add it to the vulnerability rules table in the README.
  • New fixture contracts under examples/contracts/ demonstrating a 2-hop and a 3-hop exploitable cross-contract reentrancy, plus a correctly guarded (non-vulnerable) equivalent for false-positive testing.
  • Unit tests covering: direct 2-hop reentrancy, 3-hop reentrancy through an intermediate contract, correctly guarded chains producing no finding, and a depth-limited case that should not be flagged beyond the configured maximum hops.

Acceptance Criteria

  • Detects the 2-hop and 3-hop fixture exploits with the full call chain reported in the finding.
  • Does not flag the guarded fixture (zero false positives on that case).
  • Analysis time on the existing examples/ fixture set stays within the current scan performance budget (no more than a small, documented constant-factor slowdown).
  • The new rule appears in the README's Vulnerability Rules table with its SWC cross-reference where applicable.

Estimated Scope

Approximately 700 lines of new TypeScript across the rule, fixtures, and tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions