Skip to content

fix: emit calls edges for Solidity modifier invocations (AGE-4)#29

Merged
saldestechnology merged 1 commit into
mainfrom
johan/age-4-solidity-modifiers-are-not-modeled-in-the-graph-no-edges-no
Jul 11, 2026
Merged

fix: emit calls edges for Solidity modifier invocations (AGE-4)#29
saldestechnology merged 1 commit into
mainfrom
johan/age-4-solidity-modifiers-are-not-modeled-in-the-graph-no-edges-no

Conversation

@saldestechnology

Copy link
Copy Markdown
Collaborator

Summary

Solidity modifier applications (function f() external onlyOwner) produced no edge in the code graph, so ctx query callers onlyOwner, ctx query impact, and v1.edges could not answer access-control / reentrancy-guard questions — a core audit surface.

Note: modifier definitions were already emitted as symbols (extract_function handles FunctionTy::Modifier). The only gap was the edge from a function to the modifier it applies, because func.attributes was only inspected for visibility and FunctionAttribute::BaseOrModifier was never matched.

Change

  • New extract_modifier_edges in src/parser/solidity.rs, invoked for both contract-member and free functions during the call-edge pass. For each FunctionAttribute::BaseOrModifier(_, base) it:
    • takes the modifier/base name (last segment of the IdentifierPath),
    • resolves source_id via the existing func_ranges line lookup,
    • resolves target_id against the modifier's Function symbol (so the edge participates in fan_in/impact traversal, which only follows kind='calls' edges with non-null target_id),
    • pushes an EdgeKind::Calls edge.
  • Reuses SymbolKind::Function and EdgeKind::Calls — no model, Cargo, or query-layer changes.
  • Also covers constructor base-contract invocations (constructor() Ownable(msg.sender)), emitting an edge with target_id resolved when a matching symbol exists, None otherwise (mirroring unresolved calls).

Tests

Extends test_parse_constructor_and_modifiers to assert a calls edge to onlyOwner exists with target_id resolved to the modifier symbol.

  • cargo fmt --all -- --check
  • cargo clippy --all-targets -- -D warnings ✅ (0 warnings)
  • cargo test ✅ (303 lib + all integration suites pass, 0 failures)

Refs AGE-4. Sibling of AGE-2 (duplicates skip Solidity) and AGE-5 (qualified-call resolution).

Applying a modifier to a function (e.g. `function f() onlyOwner`) produced
no edge in the code graph, so `ctx query callers <modifier>`, `impact`, and
`v1.edges` could not answer access-control questions. Modifier *definitions*
were already emitted as symbols; only the edge was missing.

Add `extract_modifier_edges`, which walks each function's
`FunctionAttribute::BaseOrModifier` attributes and emits a `calls` edge from
the function to the modifier, resolving `target_id` against the modifier
symbol so it participates in fan_in/impact traversal. Also covers constructor
base-contract invocations. Includes a parser test asserting the resolved
edge.

Refs AGE-4
@saldestechnology
saldestechnology force-pushed the johan/age-4-solidity-modifiers-are-not-modeled-in-the-graph-no-edges-no branch from e14986a to ac295b2 Compare July 11, 2026 14:19
@saldestechnology
saldestechnology merged commit 134ad56 into main Jul 11, 2026
6 checks passed
@saldestechnology
saldestechnology deleted the johan/age-4-solidity-modifiers-are-not-modeled-in-the-graph-no-edges-no branch July 11, 2026 15:13
saldestechnology added a commit that referenced this pull request Jul 11, 2026
…es + edges, providers) (#33)

The AGE-2/3/4/5 PRs (#29-#32) shipped behavior changes without doc
updates. Bring docs/website in line:

- index/embed run in parallel by default; document --serial and demote
  -j/--parallel to a retained no-op (indexing, getting-started,
  code-intelligence help snapshots + synopsis)
- ctx duplicates now fingerprints Solidity via the solang-parser lexer;
  drop the "skipped" caveats and set skipped_languages: []
  (duplicates, code-intelligence, json-output, score)
- Solidity modifier applications emit calls edges and qualified library
  calls Lib.fn() resolve (language-support)
- round out provider docs: add Ollama to the embed providers table and
  offer --provider <local|openai|ollama> in similar/smart (code-intelligence,
  similar, smart)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant