Arena Contract Bug: `claim()` Payouts Lack Survivor Registration Check, Risking Unearned Prize Drain
A critical security flaw in the arena smart contract allows the prize pool to be paid out to any address designated as a winner, even if that address never registered as a participant. The `claim()` function fails to verify that the winner is also a registered `Survivor`, creating a direct path for unearned funds to be drained from the contract.
The bug stems from a separation in the contract's data keys. The `set_winner()` function, which is admin-only, sets a `DataKey::Winner` for a given player address. However, the `claim()` function only checks for this winner key and that the prize pool is non-zero before authorizing a token transfer. It performs no cross-reference with the `DataKey::Survivor` key, which is established when a player legitimately joins the game via the `join()` function. Consequently, an admin could—intentionally or accidentally—set a winner for an arbitrary address that never participated, and that address could then successfully claim the entire prize.
This vulnerability undermines the core game logic and trust in the contract's reward distribution. The `get_user_state()` view function compounds the issue by incorrectly returning `has_won: true` for any address with a winner key, regardless of its survivor status, potentially misleading off-chain interfaces. The absence of this fundamental check represents a significant logic flaw, exposing the prize pool to misallocation and demanding immediate remediation to prevent exploitation and financial loss.