The intended behavior is that a player can take the stage as a defender by staking a CRED
token bet and locking their NFT. Another player can then challenge with a matching bet and their NFT, after which the contract determines a winner and pays out the pooled bets.
The problem is that once a defender goes on stage, there is no mechanism for the defender (or anyone else) to cancel or withdraw if no challenger arrives. This allows a defender to lock the arena indefinitely or set a bet size that no one can match, blocking the arena for all other players. In the process, the defender’s bet and NFT are also locked forever.
Likelihood:
A defender always sets arena.defender
and arena.defender_bet
when going on stage, with no timeout or cancel function.
Attackers can trivially call this once with a very high bet or simply never intend to battle, leaving the arena locked.
Impact:
Denial of Service: No other users can use the arena once locked.
Permanent loss of funds/NFT: Defender’s stake and NFT remain trapped unless a challenger with the exact bet appears — which may never happen.
Add a cancellation or timeout mechanism that allows a defender to reclaim their NFT and bet if no challenger arrives:
Alternatively, enforce a time-based expiration (e.g., using timestamp::now_seconds()
) so that if no challenger joins within X
seconds, the defender can safely withdraw.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.