58146 sc insight whitelist can be disabled repeatedly contradicting intended program behavior

#58146 [SC-Insight] Whitelist can be disabled repeatedly, contradicting intended program behavior.

Submitted on Oct 30th 2025 at 23:17:47 UTC by @chief_hunter888 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58146

  • Report Type: Smart Contract

  • Report severity: Insight

  • Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/utils/Whitelist.sol

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

Description

# Whitelist.disable() in Whitelist.sol can be called repeatedly contradicting intended program outcomes

Brief Summary

IWhitelist.sol NatSpec states that disable() can only occur once'' and cannot be reenabled.'' The implementation, however, does not enforce a one-time-only disable: calling disable() multiple times is possible, and each call emits another WhitelistDisabled event. This breaks the promised invariant and can confuse/harm off-chain consumers and waste gas.

Please refer to the POC test below.

Please refer to the POC attached below.

It follows these steps: Evidence / reproduction

  1. Deploy Whitelist (implements IWhitelist).

  2. Call disable() → WhitelistDisabled event is emitted and whitelist is disabled.

  3. Call disable() again → call succeeds again and a second WhitelistDisabled event is emitted.

Why this is a bug

The NatSpec contract-level promise (semantic invariant) claims that the disable function is a single irreversible function, but the code allows repeated disables. That mismatch is a correctness/contractual bug.

Off-chain systems and backends often rely on event semantics (e.g., first WhitelistDisabled events for a canonical transition). Multiple identical disable events can confuse indexing, lead to incorrect state assumptions, or create noisy logs. Repeated calls waste gas for callers and can hide the true moment of transition (first disable) in logs/analytics.

Even if repeated disables cause no on-chain safety hazard, the mismatch between documentation and behavior is a reliability/maintenance issue.

Bug Impact

Backend/indexers may record multiple disable events and either: (a) misinterpret which one is authoritative, or (b) need extra code to deduplicate — both add complexity and risk.

Admin is paying gas to call disable() again are wasting funds.

Degrades trust in the contract API and NatSpec guarantees.

Suggested remediation (short)

Enforce a one-time disable in code and revert on repeated calls, or update NatSpec to match current behavior.

Fix option A — enforce one-time disable (recommended)

Add a boolean guard and revert if already disabled:

bool public disabled;

event WhitelistDisabled(address indexed caller);

Fix option B — document current behavior (less desirable)

If repeated disables are intended, update NatSpec to remove the “only once” claim and state that calling disable() is idempotent and may emit multiple events. Prefer adding a guard instead of relying on idempotent events.

Ensure off-chain indexer picks up the first WhitelistDisabled event as the canonical transition (documented).

References

The defining natspec in IWhitelist.sol

https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/utils/Whitelist.sol?utm_source=immunefi

Proof of Concept

Proof of Concept

Please add this file as Whitelist.t.sol to your test/ suit and run the poc using:

Was this helpful?