The upgrade function is controlled by a single owner/EOA with no timelock. That key can swap in malicious implementation code instantly, draining all funds with zero warning to users.
// owner upgradeTo(EvilImpl) where EvilImpl.withdrawAll() sends funds // to the owner. No delay -> users cannot exit before the drain.
// gate _authorizeUpgrade behind a timelock/multisig with a delay function _authorizeUpgrade(address) internal override onlyRole(UPGRADER_ROLE) {} // where UPGRADER_ROLE is held only by a timelock
Largest recorded losses in the same failure class — related, not the same bug:
The SaferICO scanner runs 201 detectors over your Solidity source, SAFE-0232 among them. Paste an address or the source itself — a small per-scan fee, shown before you sign, or unlimited on any plan.