51951 sc low a global blocking check in claimprize prevents individual winner claims until all winners are drawn

Submitted on Aug 6th 2025 at 19:57:08 UTC by @XDZIBECX for Attackathon | Plume Network

  • Report ID: #51951

  • Report Type: Smart Contract

  • Report severity: Low

  • Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/spin/Raffle.sol

  • Impacts:

    • Permanent freezing of funds

Description

Brief / Intro

The claimPrize function contains a validation logic flaw that creates a global blocking mechanism preventing any winner from claiming their prize until all winners for that specific prize have been drawn.

The function checks two conditions together:

  • whether the prize is still active: prizes[prizeId].isActive

  • whether the number of winners drawn is less than the total quantity: winnersDrawn[prizeId] < prizes[prizeId].quantity

If both conditions are true, the function reverts and blocks the claim attempt entirely. This global check occurs before any individual winner validation, meaning a legitimately selected winner is blocked if other winners for the same prize haven't been drawn yet.

The bug stems from a misunderstanding of multi-winner behavior: treating all winners as a single unit rather than allowing individual winners to claim their prizes independently once they have been selected.

Vulnerability Details

The issue in claimPrize prevents any winner from claiming their prize until all winners for a given prize have been drawn. This violates the intended multi-winner design documented for the raffle:

"Each winner must call claimPrize(prizeId, winnerIndex) to claim their specific prize. Since a prize can have multiple winners, the winnerIndex (starting from 0) is used to identify which winning slot is being claimed. Each winner's claim status is tracked independently. One user claiming their prize has no effect on the ability of other winners to claim theirs."

Vulnerable snippet (source pointer): https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/plume/src/spin/Raffle.sol#L299C5-L304C1

Example problematic code:

Because the contract reverts the claim for any winner if the prize is still active (meaning more winners are yet to be drawn), as long as any winner remains undrawn for a prize, no winner can claim—regardless of whether their own win has been selected and recorded in prizeWinners. There is no on-chain timeout, expiry, or bypass to allow individual winners to claim independently.

Impact Details

This bug can permanently prevent legitimately selected winners from claiming their prize unless all winners for the prize are drawn. If the admin fails to draw all winners, prizes for that round could be frozen and unclaimable. Winners recorded in the contract would be blocked from accessing their rewards, potentially resulting in a permanent freeze of funds unless resolved via external intervention (e.g., contract upgrade).

Proof of Concept

References

  • https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/plume/src/spin/Raffle.sol#L299C5-L304C1

Was this helpful?