# DoS and gas griefing of calls to Prime.updateScores()

Prime.updateScores() skips the i++ on the continue path, so an attacker frontrunning with one already-updated user makes the batch call loop forever and OOG-revert.

- Payout: Contest reward
- Severity: medium
- Program: Venus Protocol
- Credited: 0xDetermination
- Disclosed: 2023-11-29
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-09-venus-findings/issues/556
- Library page: https://bugbountylibrary.com/r/c4%3A2023-09-venus%3AM-02
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window technique:source-review vuln:business-logic vuln:dos

**Target:** Prime.sol updateScores() batch score-update function
**Root cause:** The for-loop increments i only inside the unchecked block at the end of the body; the `continue` on an already-updated user skips the increment, so i never advances and the loop spins until out-of-gas.
**Steps:**
1. Issue Prime tokens to user1, user2, user3 and deposit XVS into xvsVault for each.
2. Call `prime.updateAlpha(1, 5)` to make pendingScoreUpdates nonzero.
3. Attacker frontruns with `prime.updateScores([user3])`, marking user3 as score-updated for the round.
4. Victim calls `prime.updateScores([user1, user2, user3])`; on reaching user3 the `continue` skips `i++`, loop never terminates, call reverts OOG.
5. Repeat frontrun each retry to burn the victim's gas.
**How found:** Code reading of the updateScores loop: noticing `i++` lives inside the unchecked block after the `continue`, meaning the skip path never increments the index.
**Exploitation:** Attacker watches the mempool for a batch updateScores() call, extracts one address from its argument array, and submits updateScores([thatAddress]) with higher gas. The victim's call then hits the already-updated user, `continue` skips the increment, and the loop runs out of gas, reverting the whole batch and wasting the caller's gas; attacker pays only ~10k gas per grief.
**Escalation:** Repeated frontrunning forces the legitimate updater to repeatedly spend the full batch gas (e.g. 1M gas for 100 users) while scores stay stale, so rewards are distributed incorrectly until updates succeed.
**Insight:** When auditing batch loops, check whether every `continue`/early-exit path still advances the index; a `continue` before an increment inside `unchecked` turns any externally pre-settable 'already done' flag into a permanent OOG DoS.
