feat(lint): add reentrancy-unlimited-gas#15768
Conversation
| "state read before external call is written after the call" | ||
| ); | ||
|
|
||
| declare_forge_lint!( |
There was a problem hiding this comment.
solc 0.8.31 already warns on every built-in send/transfer and recommends call, so this duplicates a recent compiler diagnostic while adding flow-analysis false positives. per #14381, can we omit this detector?
There was a problem hiding this comment.
I kept the detector because #14381 explicitly tracks it and Foundry linting also serves projects on older compiler versions or with compiler diagnostics configured differently. The reviewed implementation is path-aware and now excludes failed sends, rollback-only effects, and other false-positive shapes. I am leaving this policy thread open for maintainer preference.
Detect resolved transfer and send builtins followed by reachable state writes or event emissions. Reuse the existing reentrancy path analysis while excluding custom same-named contract members.
Resolve transfer and send through Solar's exact builtins and conservatively follow reachable effects through expressions, internal calls, storage aliases, modifiers, and loop backedges. Exclude failed-send and non-returning continuations, and preserve existing reentrancy lint behavior.
Track stored send outcomes through control flow while invalidating overwritten results. Model do-while and Yul loop transitions, preserve successful halt effects, discard rollback-only unordered paths, and recognize Yul storage and log effects.
1a1ab01 to
915e068
Compare
Track tuple slots and internal helper return sources so failed-only send paths are pruned without hiding success or unknown-path reentrancy warnings.
Align tuple assignment structure recursively and apply result writes in Solidity order. Preserve holes, sibling isolation, stale-source clearing, and duplicate-variable overwrite semantics.
Keep send success correlated through composed boolean expressions so failure-only branches do not produce reentrancy warnings.
| { | ||
| candidate_state.set_stored_call_results(expr.span, &return_sources); | ||
| returned_state.merge(&candidate_state); | ||
| any_returns = true; |
There was a problem hiding this comment.
Send-result correlation is lost when passed into an internal helper: bool ok = recipient.send(1); failedOnly(ok), with if (!ok) counter = 1, warns even though the write is failure-only. Please bind actual send-result sources to the callee parameters and retain a success-path control.
This adds the info-severity
reentrancy-unlimited-gaslint from #14381. It reports Solidity's built-intransferandsendwhen a persistent state write or event emission remains reachable after a successful interaction, without treating the fixed stipend as a reentrancy boundary.The flow analysis resolves builtins semantically and follows helpers, modifiers, inheritance, branches, loops, storage aliases, and Yul effects. Stored
sendresults are tracked as must-facts across assignments and joins, invalidated by overwrites and repeated static spans, and used to prune failed-only paths. Rollback-only siblings, non-returning paths, and failed sends do not report; do-whilecontinuetransitions and Yulsstore,tstore, logs, switches, helpers, and loop posts are modeled explicitly. Fresh-context reviews added regressions for every corrected path and found no remaining issues.The user documentation is in foundry-rs/book#1983, with the review-aligned flow follow-up in foundry-rs/book#1996.
Prepared with assistance from OpenAI Codex.