# Bad implementation in minter access control for RabbitHoleReceipt and RabbitHoleTickets contracts

onlyMinter modifier in RabbitHoleReceipt and RabbitHoleTickets lacks require, so anyone can mint receipt NFTs and steal quest rewards.

- Payout: Contest reward
- Severity: high
- Program: RabbitHole
- Credited: adriro
- Disclosed: 2023-04-11
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-rabbithole-findings/issues/608
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-rabbithole%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Solidity ERC721/ERC1155 mint access control modifier
**Root cause:** The onlyMinter modifier evaluates `msg.sender == minterAddress` as a bare expression without require/revert, so the comparison result is discarded and execution always continues.
**Steps:**
1. Deploy RabbitHoleReceipt/RabbitHoleTickets behind proxies and initialize with a minter address
2. As any attacker address, call `receipt.mint(attacker, "a quest")`
3. Call `tickets.mint(attacker, 0, 1, "")`
4. Observe balanceOf(attacker) == 1 for both, confirming unrestricted mint
**How found:** Code review of the mint functions and their onlyMinter modifier; noticed the modifier body is a bare comparison with no require, so it never reverts.
**Exploitation:** Attacker mints RabbitHoleReceipt tokens tagged with a target questId, then claims quest rewards with the forged receipts to drain the quest's reward pool.
**Insight:** When auditing modifiers, verify the condition is actually enforced (require/revert/if-revert); a bare boolean expression in a modifier silently no-ops and is easy to miss in diff review.
