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.


Maintainer Scope Upgrade

This issue is being expanded into a substantial, production-quality ChainProof enhancement. The implementation should be designed as maintainable platform work, not as a narrow proof of concept. A successful pull request must provide a cohesive user-facing capability, typed internal APIs, robust tests, documentation, and CI-safe behavior.

Expanded Objective

Implement CP-121 as a multi-hop, cross-contract reentrancy detector using resolved import and call-graph context. The feature should fit the existing monorepo architecture, reuse current scanner/report/CLI patterns where appropriate, and avoid introducing ad hoc subsystems that are difficult to test or maintain.

Required Implementation Depth

This issue is intentionally scoped to require more than 700 lines of meaningful implementation work. The line count expectation applies to purposeful source, tests, fixtures, and documentation that are necessary to deliver the feature. It must not be satisfied through generated output, lockfile churn, formatting-only changes, duplicated boilerplate, or artificial padding.

Expected work includes:

  • Cross-contract call-chain traversal with bounded depth, cycle handling, state-finalization analysis, and reentrancy-guard recognition.
  • 2-hop and 3-hop exploit fixtures plus guarded equivalents, with findings that report the complete actionable path.
  • Integration with scanner configuration, Slither deduplication, documentation, and performance regression coverage.
  • Public or internal types/interfaces where they clarify behavior and reduce future integration risk.
  • Failure-mode handling for invalid input, missing configuration, unavailable optional dependencies, and degraded execution paths.
  • Documentation updates that explain how maintainers and users should operate the new capability in local and CI environments.

Professional Quality Bar

The implementation must be production-ready and reviewable in isolation. Contributors should include clear separation between parsing, analysis, reporting, CLI/action integration, and persistence or provider code where those concerns apply. The code should follow existing ChainProof conventions, keep behavior deterministic in tests, and avoid coupling core analysis to network-only services unless explicitly optional and mocked.

Acceptance Criteria

  • The delivered PR contains more than 700 meaningful lines of implementation across source, tests, fixtures, and docs, excluding generated files and lockfile-only changes.
  • The feature is integrated into the relevant package entrypoints, CLI commands, report formats, GitHub Action behavior, or documentation as appropriate for this issue.
  • Unit tests cover normal operation, edge cases, invalid inputs, and at least one realistic fixture or end-to-end workflow.
  • Any optional external service, model provider, database, or platform integration has deterministic mocks or fallbacks so CI does not depend on secrets or network availability.
  • User-facing output is documented and stable enough for downstream automation.
  • Backward compatibility is preserved unless the PR explicitly documents a migration path and the maintainer approves it.

Mandatory CI and Merge Requirements

A PR resolving this issue must not be merged until all repository CI checks pass. At minimum, reviewers should verify the following from a clean checkout:

  • npm ci
  • npm run lint
  • npm run build --workspaces --if-present
  • npm run test:ci --workspace=packages/core
  • npm test --workspaces --if-present
  • npm run build --workspace=packages/core && npm run docs --workspace=packages/core
  • Any package-specific tests, examples, validators, or integration checks introduced by the PR

If the PR adds a GitHub Action, report format, dashboard, persistence layer, or external integration, it must also include CI coverage or a documented local verification command for that path. Known warnings are acceptable only when they are documented and do not hide failures.

Review Expectations

Reviewers should reject PRs that only stub APIs, add superficial wrappers, omit tests for critical behavior, rely on live secrets in CI, or meet the line-count target through non-functional bulk changes. The preferred solution is a focused but complete vertical slice that leaves ChainProof more reliable, easier to operate, and easier to extend.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third CampaignenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions