Last Man Standing

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

Incorrect King Check Causes Game Lock in claimThrone()

Root + Impact

Description

  • The expected behavior is that a player can claim the throne as long as they are not the current king, allowing the game to progress normally.

  • The issue is that the condition require(msg.sender == currentKing, ...) forces the caller to be the current king to proceed, which contradicts the intended logic. This causes the function to revert when the caller is not the king. Moreover, the revert message does not match the condition, causing confusion.

// Root cause in the codebase with @> marks to highlight the relevant section
function claimThrone() external payable gameNotEnded nonReentrant {
require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
// rest of the code
}

Risk

Likelihood:

  • Occurs whenever a player tries to claim the throne and is not the current king, which is the normal use case.

  • Occurs immediately after deployment when currentKing is the zero address, preventing anyone from claiming the throne initially.

Impact:

  • Blocks normal game progression by preventing legitimate throne claims.

  • Confuses users and developers due to contradictory revert messages and faulty logic.

  • Could cause a denial of service on the game’s core functionality, effectively freezing part of the contract.


Proof of Concept

This PoC demonstrates that, starting from the initial state where no king is set, any attempt to claim the throne reverts due to the faulty require condition, effectively blocking gameplay.

// Deploy contract with currentKing == address(0)
// Attempt to call claimThrone() from any address with sufficient ETH
// The transaction reverts with "Game: You are already the king. No need to re-claim."

Recommended Mitigation

Changing the condition to require that the caller is not already the current king ensures that the function only reverts when a player tries to claim the throne they already hold, enabling normal gameplay progression.

- 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.");
Updates

Appeal created

inallhonesty Lead Judge about 1 month 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.