Last Man Standing

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

Logic Error in claimThrone() Prevents Game from Starting and Locks Funds

Logic Error in claimThrone() Prevents Game from Starting and Locks Funds

Description

  • The claimThrone() function in Game.sol contains a faulty require condition:

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

This condition is intended to prevent the current king from re-claiming the throne. However, it is logically incorrect — it only allows the current king to claim the throne again, and blocks all other users.

At the start of the game, currentKing is uninitialized and defaults to address(0). As a result, no address other than address(0) can pass this condition, meaning the game cannot be started by any player.

Risk

Likelihood:

  • This issue will always occur on the very first call to claimThrone(), because the currentKing is uninitialized and defaults to address(0), which no real user can ever match.

  • Any subsequent attempt by real users to start the game will consistently revert, rendering the game unplayable until the faulty logic is corrected.

Impact:

  • All ETH sent to the contract (e.g., via fallback or receive() functions) will be permanently locked, since no one can become king and trigger a game cycle.

  • Core game functions such as declareWinner() and resetGame() will never be reachable, effectively making the contract unusable and the game logic broken from the outset.

Proof of Concept

The logic error in claimThrone() can be reproduced using a simple Foundry test. The following test function was added to the test/Game.t.sol file:

function testFirstClaim_RevertBecauseNotCurrentKing() public {
vm.prank(player1);
vm.expectRevert("Game: You are already the king. No need to re-claim.");
game.claimThrone{value: INITIAL_CLAIM_FEE}();
}

This test simulates the first user (player1) attempting to claim the throne immediately after contract deployment. Since the currentKing is uninitialized and defaults to address(0), the require(msg.sender == currentKing) condition fails, and the transaction reverts as expected.

The revert message confirms the vulnerability:

"Game: You are already the king. No need to re-claim."

This validates that no player can ever become the first king, and the game is effectively locked.

Recommended Mitigation

Replace the incorrect require logic:

This ensures:

  • A new player (not the current king) can claim the throne

  • The game can start properly with the first user

  • Logic matches the intended gameplay

- 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 2 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.