Skip to content

re-initialization-risk guard detection fires on any unrelated .has()/.is_some()/.is_none() call #367

Description

@unrealtim-tech

Labels: bug, checks-crate
Crate: checks

Description
crates/checks/src/reinit.rs (lines ~66-90) sets has_guard = true on any method call named has, is_some, or is_none anywhere in the function body, with no check that the call actually gates the storage write it's supposed to protect:

if matches!(method.as_str(), "has" | "is_some" | "is_none") {
    self.has_guard = true;
}

An initialize function that checks an unrelated Option before unconditionally writing admin to storage is treated as guarded against re-initialization, even though nothing actually prevents the function from being called twice:

pub fn initialize(env: Env, admin: Address, referrer: Option<Address>) {
    if referrer.is_some() { /* unrelated logic, e.g. logging a referral */ }
    env.storage().instance().set(&ADMIN, &admin);   // no actual re-init guard
}

Acceptance Criteria

  • Require the guard call to be on the same storage key/receiver being written, and to actually control (via if/early-return) whether the write executes, rather than any presence-check anywhere in the function.
  • Add a test with an unrelated is_some() call plus an unguarded re-initializable write, asserting a finding is still produced.

Difficulty: intermediate

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stellar WaveIssues in the Stellar wave programbugSomething isn't workingchecks-crate

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions