Last Man Standing

First Flight #45
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

Incorrect Access Check Locks the Game

Root + Impact

Description

  • Normal behavior: When a new player wants to claim the throne, they should be allowed to do so if they send at least the current claimFee and are not already the current king.

  • Issue: The check in claimThrone() is inverted. It requires msg.sender to equal currentKing instead of ensuring it is not the current king, effectively allowing only the current king to call the function:

    require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim.");

    This prevents any other participant from becoming king and freezes the game after the first claim.

Risk

Likelihood:

  • The bug occurs every time a non‑king calls claimThrone().

  • After the first claim, everyone else will revert, so the game cannot progress.

Impact:

  • Denial of Service: New players can never claim the throne.

  • Economic Loss: Participants lose gas on reverting transactions.

  • Reputation Risk: The game cannot function as intended, undermining user trust.

Proof of Concept

// Assume Alice calls claimThrone() and becomes currentKing.
vm.startPrank(alice);
game.claimThrone{ value: INITIAL_CLAIM_FEE }();
vm.stopPrank();
// Bob sends the required fee and tries to dethrone Alice.
vm.startPrank(bob);
vm.expectRevert();
game.claimThrone{ value: game.claimFee() }(); // reverts because bob != currentKing
vm.stopPrank();

Recommended Mitigation

function claimThrone() external payable gameNotEnded nonReentrant {
require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
- require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim.");
+ require(msg.sender != currentKing, "Game: You are already the king. No need to re-claim.");
// rest of logic stays the same
}
Updates

Appeal created

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Game::claimThrone `msg.sender == currentKing` check is busted

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!