Last Man Standing

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

Incorrect claimThrone Logic

Incorrect checks in claimThrone Method, Causing No new player can participate after the first claim.

Description

  • Normally, any player except the current king should be able to claim the throne by paying the claim fee.

  • The contract currently only allows the current king to claim the throne, which breaks the intended game logic and makes the game unplayable for new participants.

// src/Game.sol
function claimThrone() external payable gameNotEnded nonReentrant {
...
@> require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim."); //@> Only current king can claim
...
}

Risk

Likelihood:

  • This will occur every time a non-king tries to claim the throne, as the require statement blocks them.

  • The game cannot progress beyond the first king.

Impact:

  • No new players can participate after the first claim.

  • The game logic and incentives are completely broken.

Proof of Concept

To demonstrate the i issue, we need to show that only the current king can claim the throne, and any other player will be reverted by the contract.
This breaks the intended game flow, as new players should be able to claim the throne.

Test Setup to Prove the Issue

Add the following test to your GameTest.sol to show that a non-king cannot claim the throne:

// Any address other than currentKing calls claimThrone()
// Transaction reverts with "Game: You are already the king. No need to re-claim."
function testClaimThrone_RevertForNonKing() public {
// Start as player1 and claim the throne (should succeed if player1 is the first king)
vm.startPrank(player1);
game.claimThrone{value: INITIAL_CLAIM_FEE}();
vm.stopPrank();
// Now player2 tries to claim the throne (should revert due to incorrect logic)
vm.startPrank(player2);
vm.expectRevert("Game: You are already the king. No need to re-claim.");
game.claimThrone{value: INITIAL_CLAIM_FEE}();
vm.stopPrank();
}

Recommended Mitigation

Change the require statement to prevent the current king from reclaiming, allowing others to claim:

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