Skip to content

fix: harden G016/G017 rules, wire up heatmap reporter, and cover assembly-log event topics - #757

Merged
mijinummi merged 1 commit into
MDTechLabs:mainfrom
silifatzoffun74-art:feat/issues-731-730-729-728-improvements
Jul 31, 2026
Merged

fix: harden G016/G017 rules, wire up heatmap reporter, and cover assembly-log event topics#757
mijinummi merged 1 commit into
MDTechLabs:mainfrom
silifatzoffun74-art:feat/issues-731-730-729-728-improvements

Conversation

@silifatzoffun74-art

Copy link
Copy Markdown
Contributor

Context

Issues #731, #730, #729, and #728 were originally implemented in PR #716 (merged as commit 89801da), but the issues were left open. This PR does not duplicate that work — it adds concrete, itemized improvements on top of it, addressing gaps against each issue's own acceptance criteria.

What changed

G016 — Redundant address casts (#729)

rules/g016_redundant_casts.rs previously only did a flat substring search for address(uint160( / address(payable(, so it missed deeper chains and had no protection against matching inside comments.

  • Added detection for address(uint160(uint256(x))) and address(payable(uint160(x))) / payable(address(uint160(x))) chains.
  • Added comment stripping so mentions of the pattern inside // or /* */ comments no longer produce false positives.
  • Added unit tests covering the new positive cases plus the issue's own negative case: "does not flag necessary bytes32 -> address conversions".
  • Extended test/fixtures/g016_samples.sol with the new positive/negative cases.

G017 — Enum iteration (#731)

rules/g017_enum_iteration.rs previously flagged any loop as soon as the contract contained any enum keyword anywhere in the file — which fails the issue's own acceptance criterion "Passes cleanly on standard integer index loops" (a plain for loop over an array in a contract that happens to declare an enum elsewhere was incorrectly flagged).

  • Rewrote the check to isolate each loop body (including nested loops) and only flag loops that actually cast their index variable into a known enum type via EnumType(i).
  • Added while-loop and nested-loop coverage.
  • Added unit tests for both positive cases (for/while/nested) and negative cases (plain integer loops, enum casts outside a loop, no enums declared).
  • Extended test/fixtures/g017_samples.sol accordingly.

Event topics (#730)

test/events/EventRegistry.test.ts was a placeholder (expect(true).to.be.true) that never actually verified the topic constants.

  • Added EVENT_APPROVAL_FOR_ALL_TOPIC and EVENT_OWNERSHIP_TRANSFERRED_TOPIC constants.
  • Added emitViaAssembly(), demonstrating the issue's second requirement — a low-level log call consuming a compile-time constant topic directly — which wasn't previously demonstrated anywhere in the contract.
  • Replaced the placeholder test with real assertions that each topic constant equals ethers.id(...) of its canonical event signature, plus tests for both logEvent and emitViaAssembly.

Heatmap reporter (#728)

gasguard-cli/src/reporter was never declared as a module in gasguard-cli/src/lib.rs, so heatmap.rs was dead code, not compiled into the crate at all.

  • Wired pub mod reporter; into lib.rs.
  • Added format_legend() / format_report() describing the tier thresholds and colors, so output is self-describing in CI logs.
  • Added visual severity bars per tier (the issue's "summary visual bars" requirement, not previously implemented).
  • Functions with no gas estimate now render as an explicit N/A tier instead of silently falling into the LOW bucket.
  • Added unit tests covering tier boundaries, zero-gas handling, missing-data handling, and --no-color vs. color output.

Testing

  • rustc --edition 2021 --test rules/g016_redundant_casts.rs — 6/6 passing
  • rustc --edition 2021 --test rules/g017_enum_iteration.rs — 6/6 passing
  • cd gasguard-cli && cargo test — 32/34 passing (the 2 failures are in commands::optimize_storage, pre-existing on main and unrelated to this change)
  • Verified contracts/events/EventRegistry.sol compiles standalone via solc; full-repo hardhat compile currently fails on main due to unrelated pre-existing syntax errors in other contracts (StorageCleaner.sol, BatchGuardProcessor.sol, UnrolledSignatureVerifier.sol, YulMathLib.sol, DirectIndexRouter.sol), confirmed unaffected by this branch.

Closes #731
Closes #730
Closes #729
Closes #728

…mbly-log event topics

PR MDTechLabs#716 previously landed the initial implementations for issues
MDTechLabs#731, MDTechLabs#730, MDTechLabs#729, and MDTechLabs#728, but each still had real gaps against its
original acceptance criteria:

- G016 (redundant address casts): the check only did a flat substring
  search, so it missed deeper chains like
  address(uint160(uint256(x))) and address(payable(uint160(x))), and
  had no safeguard against matching inside comments. Added detection
  for those chains, comment stripping, and unit tests covering both
  the new positive cases and the "does not flag necessary bytes32 ->
  address conversions" negative case called out in the issue.

- G017 (enum iteration): the check only looked for "any loop" plus
  "any enum keyword anywhere in the file", which fails the issue's own
  acceptance criterion of "passes cleanly on standard integer index
  loops" (it flagged unrelated loops whenever an enum was declared
  anywhere in the contract). Rewrote it to isolate each loop body and
  only flag loops that actually cast their index into a known enum
  type, added nested-loop and while-loop coverage, and added unit
  tests for both positive and negative cases.

- Event topics (MDTechLabs#730): EventRegistry.sol's test file was a placeholder
  that asserted `true == true` and never verified the topic constants.
  Added ApprovalForAll/OwnershipTransferred constants, an
  emitViaAssembly() function demonstrating a low-level log call
  consuming a compile-time constant topic directly (per the issue's
  second requirement, which wasn't previously demonstrated), and a
  real test suite that checks each constant against ethers.id(...) of
  its canonical signature.

- Heatmap reporter (MDTechLabs#728): reporter::heatmap was never declared in
  gasguard-cli's lib.rs, so it was dead code not compiled into the
  crate at all. Wired it up, added a legend describing the tiers and
  colors, added visual severity bars (the "summary visual bars"
  requirement wasn't previously implemented), and made functions with
  no gas estimate render as an explicit N/A tier instead of silently
  falling into the LOW bucket.

Closes MDTechLabs#731
Closes MDTechLabs#730
Closes MDTechLabs#729
Closes MDTechLabs#728
@drips-wave

drips-wave Bot commented Jul 31, 2026

Copy link
Copy Markdown

@silifatzoffun74-art Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@mijinummi
mijinummi merged commit 7f1d98a into MDTechLabs:main Jul 31, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants