# DoS in MergingPool::claimRewards function and potential DoS in RankedBattle::claimNRN function if called after a significant amount of rounds passed

Unbounded loops over all rounds since last claim in MergingPool.claimRewards and RankedBattle.claimNRN make claiming gas-unbounded, eventually exceeding block gas limit.

- Payout: Contest reward
- Severity: medium
- Program: AI Arena
- Credited: ahmedaghadi
- Disclosed: 2024-05-14
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-02-ai-arena-findings/issues/868
- Library page: https://bugbountylibrary.com/r/c4%3A2024-02-ai-arena%3AM-04
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:dos

**Target:** Solidity smart contracts (MergingPool, RankedBattle)
**Root cause:** claimRewards and claimNRN iterate from numRoundsClaimed[msg.sender] to current roundId with no cap, and claimRewards has a nested loop over all winners per round, so gas grows unbounded with elapsed rounds.
**Steps:**
1. Deploy test in MergingPool.t.sol: mint 3 users, run 315 rounds picking user3 as winner every 35th round (9 wins).
2. Call `_mergingPoolContract.claimRewards(_modelURIs, _modelTypes, _customAttributes)` as user3.
3. Observe gasDiff > 4,000,000; with offset=1 and 9 wins gas > 3.4M.
4. For claimNRN: stake NRN for two users, run 315 rounds with updateBattleRecord and setNewRound, claimee wins every 35th.
5. Call `_rankedBattleContract.claimNRN()` as claimee; observe gasDiff > 1,000,000.
**How found:** Code reading of claim functions revealed loops bounded by roundId minus numRoundsClaimed with no cap, plus a nested winner loop; Foundry PoC measured gas growth.
**Exploitation:** A user who has not claimed for many rounds (or won many rounds) cannot claim because the loop over all rounds and nested winner loop exceeds block gas limit, permanently locking rewards.
**Insight:** When a claim iterates from a stored per-user checkpoint to a global counter, gas is attacker/user-controllable via elapsed time; check nested loops over per-round arrays too, and test with many rounds elapsed rather than a single round.
