# Possible scenario for Signature Replay Attack

QuestFactory.mintReceipt signs only (msg.sender, questId) with no deadline, chainid, or contract address, letting receipts be replayed across QuestFactory instances or chains.

- Payout: Contest reward
- Severity: medium
- Program: RabbitHole
- Credited: AkshaySrivastav
- Disclosed: 2023-04-11
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-rabbithole-findings/issues/107
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-rabbithole%3AM-09
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:signature-replay

**Target:** QuestFactory.mintReceipt signature validation (Solidity/EVM)
**Root cause:** Signature message commits only to msg.sender and questId_, omitting deadline, chainid, and verifying contract address, so a valid signature is not bound to a specific deployment, chain, or time.
**Steps:**
1. Sign `keccak256(abi.encodePacked(user, questId))` via `wallet.signMessage`
2. Call `mintReceipt(questId, hash, signature)` on QuestFactory A; receipt minted
3. Deploy a second QuestFactory (or use another chain) and create a quest with the same questId
4. Replay the same `(hash, signature)` on QuestFactory B; receipt minted again
5. Alternatively advance time past expiry (`evm_mine` +1 year) and replay the same signature successfully
**How found:** Code review of mintReceipt observed the signed hash only encodes msg.sender and questId_, with no nonce, deadline, chainid, or address(this); confirmed by writing Hardhat tests replaying a signature across two factory deployments and after a one-year time jump.
**Exploitation:** Attacker reuses a legitimately signed (user, questId) signature on a different QuestFactory deployment or chain where the same questId exists, minting additional RabbitHoleReceipt tokens used to claim quest rewards, draining reward pools.
**Insight:** When auditing signature-gated mint/claim functions, check the exact preimage of the signed hash: any missing domain separator (chainid, verifying contract), nonce, or deadline is a replay vector, and the strongest proof is a test that replays one signature against a freshly deployed second instance.
