★ Public initialize() without initializer modifier
A code & audits factor in the v1.7.0 rubric. Measured per protocol on a s cadence.
Methodology how we score #
**What this measures** This factor assesses whether any implementation contract in the protocol's proxy architecture exposes an initialize() function (or equivalent setup function) without OpenZeppelin's initializer modifier or an equivalent one-time-call guard. The static analyzer checks deployed bytecode for the presence of a function selector matching initialize(...) on implementation contracts (not proxies) and verifies whether the modifier's revert-if-already-initialized guard is present.
**Why it matters** An unguarded initialize() on an implementation contract allows any caller to invoke it directly, resetting ownership or critical parameters to attacker-controlled values in a single transaction. This is a known one-transaction exploit class: because the implementation's storage is separate from the proxy's storage, the attack does not affect proxy state -- but it can redirect upgrade authority or allow the attacker to call selfdestruct on the implementation, bricking all proxies pointing to it. Unstructured storage patterns in upgradeable contracts hinder static analysis; initialization guards require manual curator review. The Parity wallet freeze ($150M locked permanently) is the canonical example of an unguarded initWallet() on a library contract called by any user.
**Green / Yellow / Red** Green: all implementation contracts either call _disableInitializers() in the constructor (the OpenZeppelin-recommended pattern) or carry the initializer modifier on any initialize-type function, confirmed by static analysis of deployed bytecode. Yellow: the initializer modifier is present but the constructor does not call _disableInitializers(), leaving a narrow race condition window at deploy time. Red: an implementation contract exposes a public initialize() or similar function with no one-time-call guard, allowing any address to claim ownership or reset protocol parameters.
**Common gray cases** Curators legitimately cannot grade this factor when the protocol's source code is not verified on any explorer, making static analysis of the initialization path impossible.
***** Critical factor This factor is critical under rubric v1.7.0: a single Red assessment is sufficient to trigger a D or F grade regardless of all other category scores, because an unguarded initialize() represents a one-transaction total-compromise vector on the protocol's upgrade authority.
Measurement what to look for #
Determine whether any implementation contract exposes `initialize(…)` without the OpenZeppelin `initializer` modifier or equivalent initialization lock.