A UUPS proxy's _authorizeUpgrade is empty or unguarded, so anyone can call upgradeToAndCall and replace the implementation with arbitrary code — a complete takeover of the contract and its funds.
// function _authorizeUpgrade(address) internal override {} // no modifier! // attacker: proxy.upgradeToAndCall(Evil, initCall) // -> Evil is now the logic; attacker owns everything.
function _authorizeUpgrade(address newImpl) internal override onlyOwner {}
Largest recorded losses in the same failure class — related, not the same bug:
The SaferICO scanner runs 201 detectors over your Solidity source, SAFE-0233 among them. Paste an address or the source itself — a small per-scan fee, shown before you sign, or unlimited on any plan.