solady-ownable-init-frontrunlisted
Install: claude install-skill iktok90-design/ai-smart-contract-auditor
# Solady Ownable initializer front-run detection
## When this applies
Trigger on any of:
- `import {Ownable} from "solady/auth/Ownable.sol";` or `OwnableRoles`
- A contract calling `_initializeOwner(...)` from a public/external `initialize()` rather than the constructor
- Minimal-proxy clones (`LibClone.clone` / EIP-1167) of an Ownable implementation
- Factory deployments where `create`/`create2` and `initialize()` are two separate transactions
- Implementation contracts behind proxies (UUPS / transparent) using Solady Ownable
- Any `initialize`/`init` that is not protected by an initializer guard or atomic deploy
## Detection patterns
### Public init, non-atomic deploy (HIGH)
```solidity
contract Vault is Ownable {
function initialize(address owner) external {
_initializeOwner(owner); // reverts on 2nd call — but ANYONE can make the 1st
}
}
// Factory:
address v = LibClone.clone(impl);
Vault(v).initialize(msg.sender); // ← separate tx: front-runnable in the mempool
```
Between `clone` and `initialize`, a searcher front-runs `initialize(attacker)`. `_initializeOwner` succeeds for them; the legit call then reverts `AlreadyInitialized`.
**Signal:** `_initializeOwner` reachable from an unguarded external function and deploy/init are not in one transaction.
### Implementation left uninitialized (HIGH)
```solidity
contract Impl is Ownable {
function initialize(address o) external { _initializeOwner(o); }
}
// Impl deployed standalone, never initialize