# Hats can be overwritten

Hats protocol allowed creating a child hat under a not-yet-created admin; later creating that admin reset lastHatId, letting the child hat be re-created and its immutable properties overwritten.

- Payout: Contest reward
- Severity: medium
- Program: Hats
- Credited: Allarious
- Disclosed: 2023-02-15
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-02-hats-judging/issues/11
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-hats%3AM-16
- Tags: domain:web3 impact:integrity kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Hats.sol _createHat / createHat on-chain hat tree
**Root cause:** _createHat never verifies the admin hat exists, so a child can be created under a non-existent admin id. When the admin is later created, its lastHatId is overwritten to the child's id, making that id the next eligible hat and allowing re-creation/overwrite of the previously immutable child.
**Steps:**
1. Call `hats.getNextId(topHatId)` to get the not-yet-created admin id (e.g. 1.1.0).
2. Call `hats.createHat(emptyAdmin, _details, 10, _eligibility, _toggle, false, imageURI)` to create child 1.1.1 with maxSupply 10 and immutable config.
3. Call `hats.createHat(topHatId, _details, _maxSupply, _eligibility, _toggle, false, imageURI)` to create admin 1.1.0, which overwrites its lastHatId to 1.1.1.
4. Call `hats.createHat(emptyAdmin, _details, 20, _eligibility, _toggle, false, imageURI)` again; it returns the same child id 1.1.1.
5. Call `hats.viewHat(child1)` and observe maxSupply is now 20 despite the hat being immutable.
**How found:** Code review of _createHat: noticed no existence check on the admin parameter, then reasoned that creating the skipped admin later would overwrite lastHatId and make the already-minted child id the next eligible id, enabling re-creation.
**Exploitation:** Any wearer of a hat in the tree creates a child under a skipped (non-existent) admin id with immutable properties, then creates the skipped admin, then re-creates the child id with attacker-chosen properties (e.g. larger maxSupply, different eligibility/toggle), mutating a hat users believed immutable to rug them.
**Insight:** In hierarchical id schemes (topHat.admin.child), test creating children under skipped/not-yet-existing parent ids and check whether parent creation later resets counters like lastHatId, enabling re-creation of supposedly immutable child ids.
