# Superpositions.onlyminter() has wrong implemerantion, leading to wrong access control

SuperPositions.onlyMinter compared formImplementationId instead of the superform's state registry id, letting the wrong state registry pass the minter access check.

- Payout: Contest reward
- Severity: high
- Program: Superform Erc1155a
- Credited: chaduke
- Disclosed: 2024-02-13
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_superform_erc1155a_dec2023.pdf#3.1.1
- Library page: https://bugbountylibrary.com/r/cantina%3Asuperform_erc1155a_dec2023%3A3.1.1
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:high tech:solidity technique:source-review vuln:access-control vuln:auth-bypass

**Target:** SuperPositions ERC1155 contract minter modifier
**Root cause:** onlyMinter() compared the superform's formImplementationId (beacon id) against the state registry id of msg.sender instead of calling getStateRegistryId() on the superform, so the comparison used mismatched identifiers.
**Steps:**
1. Read `SuperPositions.onlyMinter(uint256 superformId)` at SuperPositions.sol#L69-L83
2. Observe it fetches `(, uint32 formBeaconId,) = DataLib.getSuperform(superformId)` and compares `uint32(registryId) != formBeaconId`
3. Note `registryId = superRegistry.getStateRegistryId(msg.sender)` is a state registry id, not a beacon id
4. Call any onlyMinter-gated function from a state registry whose id collides with the form's beacon id to bypass the check
5. Same flaw applies to `onlyBatchMinter()`
**How found:** Code review of the access-control modifier: noticed the comparison mixed a formImplementationId (beacon id) with a state registry id, an identifier-type mismatch.
**Insight:** When auditing modifiers that compare IDs, verify both sides are the same identifier namespace (beacon id vs state registry id); mismatched ID types silently weaken access control.
