# Users who have claimed before the update on the merkle tree will have no shares of the rewards afterward

ArcadeAirdrop blocks users who already claimed from claiming increased rewards after a merkle root update, leaving tokens stuck in the contract.

- Payout: Audit contest
- Severity: medium
- Program: Arcade.xyz
- Found by: 0x3b
- Disclosed: 2023-10-25
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2023-07-arcade#m-05
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-arcade%3AM-05
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** ArcadeAirdrop / ArcadeMerkleRewards claim function
**Root cause:** _validateWithdraw reverts with AA_AlreadyClaimed whenever claimed[msg.sender] != 0, so a user who claimed under an old merkle root can never claim again after the root is updated with higher grants.
**Steps:**
1. Alice and Bob each have 100 tokens in the merkle tree.
2. Alice calls claim and receives 100; claimed[Alice] is set to 100.
3. Owner updates the merkle root raising grants to 120.
4. Bob claims 120 successfully.
5. Alice calls claim for the 20 difference; `_validateWithdraw` hits `if (claimed[msg.sender] != 0) revert AA_AlreadyClaimed();` and reverts.
**How found:** Code review of the inherited _validateWithdraw in ArcadeMerkleRewards, noticing the claimed mapping is used as a boolean gate rather than tracking claimed amounts, combined with the expectation that the merkle root may be updated.
**Exploitation:** Not an attacker-driven exploit; the flaw is a logic/DoS condition where honest users cannot claim increased rewards and the difference stays stuck in the contract until the manager reclaims it.
**Insight:** When a merkle distributor stores only a boolean-ish claimed flag, any root update that increases grants permanently locks out prior claimers; check whether claimed amounts are tracked per-user versus a single flag.

