Skip to content

feat(lint): detect balance reentrancy - #15769

Merged
mablr merged 11 commits into
foundry-rs:masterfrom
mattsse:mattsse/lint-reentrancy-balance
Jul 22, 2026
Merged

feat(lint): detect balance reentrancy#15769
mablr merged 11 commits into
foundry-rs:masterfrom
mattsse:mattsse/lint-reentrancy-balance

Conversation

@mattsse

@mattsse mattsse commented Jul 15, 2026

Copy link
Copy Markdown
Member

This adds the high-severity reentrancy-balance lint from #14381. It reports reentrant external calls between saving address(this).balance and comparing a fresh contract balance against that stale local value on the opposite comparison operand.

The analysis follows casts, tuples, derived locals, helper parameters and returns, modifiers, inherited dispatch, loops, and both operand orders while excluding token balances, mutable storage baselines, view/static calls, overwritten baselines, and mutually exclusive checks. Explicit gas caps include the value-transfer stipend. Strict standard state-lock modifiers suppress this detector only when the same lock protects every effective mutable re-entry point, and bounded recursion remains available to the existing reentrancy detectors. Fresh-context review additionally corrected modifier ordering around the lock model.

The companion Book documentation is in foundry-rs/book#1984, with the lock and stipend follow-up in foundry-rs/book#1993. This PR was implemented with Codex assistance across code, tests, and lint documentation, then independently reviewed and corrected by fresh Codex contexts.

mattsse added 2 commits July 15, 2026 17:18
Extend the existing reentrancy analysis to track locals derived from address(this).balance and report reentrant calls followed by stale balance guards.

Register the high-severity lint and add documentation plus focused true- and false-path UI coverage.
Track native self-balance values across casts, tuples, helper boundaries, operand ordering, and loop control flow. Resolve external calls semantically while preserving view, static, storage, and stipend-capped exclusions.
Comment thread crates/lint/src/sol/high/reentrancy.rs
Comment thread crates/lint/src/sol/high/reentrancy.rs Outdated
Comment thread crates/lint/src/sol/high/reentrancy.rs Outdated
Comment thread crates/lint/src/sol/high/reentrancy.rs Outdated
Require fresh and stale balances on opposite comparison operands, model standard state-lock guards across effective entry points, restore bounded recursive entry analysis, and account for value-call gas stipends.
Comment thread crates/lint/src/sol/high/reentrancy.rs
Comment thread crates/lint/src/sol/high/reentrancy.rs
Carry stale-balance comparison and boolean path provenance through helper returns, compound assignments, and control-flow joins. This avoids false positives on complementary conditions without hiding reachable callback paths.
@mattsse
mattsse requested a review from mablr July 16, 2026 20:33
Comment thread crates/lint/src/sol/high/reentrancy.rs Outdated
Preserve address(this) provenance through locals, tuples, helper and modifier parameters, and branch-correlated call paths. Invalidate aliases on observable writes and assembly reassignment.
@mattsse
mattsse requested a review from mablr July 16, 2026 23:13
Comment thread crates/lint/src/sol/high/reentrancy.rs
Comment thread crates/lint/src/sol/high/reentrancy.rs
Propagate path constraints and self-address provenance through short-circuit expressions and helper returns so balance reentrancy diagnostics follow feasible paths.
@mablr
mablr self-requested a review July 17, 2026 15:48
Comment thread crates/lint/src/sol/high/reentrancy.rs Outdated
Comment thread crates/lint/src/sol/high/reentrancy.rs Outdated
Track internal function-pointer targets through assignments and control-flow joins so helper callbacks remain visible to the balance analysis. Recognize standard lock modifiers whose sole placeholder is nested in an unconditional block.

Amp-Thread-ID: https://ampcode.com/threads/T-019f896c-fd1a-745b-be37-de6016df1dbb
Co-authored-by: Amp <amp@ampcode.com>
mablr
mablr previously approved these changes Jul 22, 2026

@mablr mablr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mablr
mablr enabled auto-merge (squash) July 22, 2026 11:54
Comment thread crates/lint/src/sol/high/reentrancy.rs Outdated
Include statements before a nested modifier placeholder when recognizing reentrancy guards. This prevents an unlock inside the nested block from suppressing reentrancy-balance diagnostics.
mablr
mablr previously approved these changes Jul 22, 2026
Comment thread crates/lint/src/sol/high/reentrancy.rs
Preserve normalized equality predicates in reentrancy balance path state so complementary == and != branches remain mutually exclusive. Invalidate those predicates when either local operand is reassigned.
@mablr
mablr merged commit a39d841 into foundry-rs:master Jul 22, 2026
20 checks passed
@github-project-automation github-project-automation Bot moved this to Done in Foundry Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants