Last Man Standing

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

Disallowing new kings to claim thron

The `claimThrone()` function contains a logic flaw that only allows the current king to re-claim the throne. This prevents other players from participating, breaking the core mechanic of the game and causing it to lock permanently after the first successful claim.

Description

  • Normally, any player who is not the current king should be able to claim the throne by sending the required claimFee. This resets the grace period and makes them the new king.

  • However, the contract contains a faulty condition

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

  • This only allows the current king to claim the throne again, which is the opposite of the intended behavior. As a result, no new players can ever participate after the first claim, and the game logic breaks entirely.

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

Risk

Likelihood:

  • The issue happens immediately after the first player claims the throne.

  • All future attempts to claim by any other player will revert.

  • The game gets stuck in a non-functional state with 100% certainty after the initial king is crowned.

Impact:

  • Core gameplay is broken; no one can dethrone the king.

  • The game becomes unplayable, requiring a manual reset.

  • Players may lose gas or funds due to misunderstood logic.

  • Loss of trust in the game as a fair or functioning contract.


    Proof Of Concept

// Alice becomes the first king
game.claimThrone{value: game.claimFee()}({from: Alice}); // ✅ Success
// Bob tries to dethrone Alice
game.claimThrone{value: game.claimFee()}({from: Bob});
// ❌ Reverts: "Game: You are already the king."
// But Bob is NOT the king — the logic is reversed

Explanation:
The require(msg.sender == currentKing) line ensures only the king can claim again, instead of preventing the king from reclaiming. This breaks the competition loop entirely.

Recommended Mitigation

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

Explanation:
This change flips the logic to the correct behavior: prevent the current king from reclaiming the throne, while allowing all other players to do so — restoring the intended gameplay flow.

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.