# HatsSignerGate + MultiHatsSignerGate: more than maxSignatures can be claimed which leads to DOS in reconcileSignerCount

HatsSignerGate.claimSigner used a stale signerCount, letting a re-hatted signer push valid signers past maxSigners and permanently brick reconcileSignerCount.

- Payout: Contest reward
- Severity: high
- Program: Hats
- Credited: GimelSec
- Disclosed: 2023-02-15
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-02-hats-judging/issues/51
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-hats%3AH-2
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic vuln:dos

**Target:** HatsSignerGate / MultiHatsSignerGate Safe module (claimSigner, reconcileSignerCount)
**Root cause:** claimSigner trusts the cached signerCount instead of recomputing valid signers from current Safe owners, so a signer who re-wears the hat after being swapped out leaves the count stale and allows an extra claim.
**Steps:**
1. Set maxSigners=10 with 10 valid signers.
2. Signers call `Safe.addOwnerWithThreshold` to reach 11 owners.
3. One signer loses the hat; call `reconcileSignerCount()` -> signerCount=9, 11 owners.
4. That signer re-wears the hat without calling reconcileSignerCount.
5. New signer calls `claimSigner()`: `currentSignerCount(9) >= maxSigs(10)` is false, passes checks, swaps an invalid owner -> 11 valid signers.
6. Any `reconcileSignerCount()` now reverts on `validSignerCount > maxSigners`, blocking all Safe transactions.
**How found:** Code review of claimSigner's reliance on cached signerCount versus live owner set; noticed reconcileSignerCount reverts when validSignerCount > maxSigners and constructed the add-owner / lose-hat / re-hat sequence to desync the count.
**Exploitation:** A hat wearer re-acquires the signer hat after being swapped out, then a fresh signer claims, inflating valid signers beyond maxSigners and permanently reverting reconcileSignerCount until a legitimate signer voluntarily gives up their hat.
**Insight:** When a contract caches a derived count (signerCount) but validates against a live set (Safe owners), look for state transitions that change the live set without updating the cache — here losing and re-gaining a hat between reconciles — to bypass max-capacity checks.
