Last Man Standing

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

# Inverted Access Control in `claimThrone()` Prevents New Players from Joining the Game.

Instead of blocking reclaims by the current king, the function contains an inverted require condition that mistakenly permits only the current king to call claimThrone(). As a result, all new claim attempts revert, effectively preventing any player from participating and blocking game progression.

Description

  • The claimThrone() function should allow any new player (who is not the current king) to claim the throne by sending the required ETH fee, updating the game state with the new king and adjusting the pot and claim fee accordingly.

  • Instead of blocking reclaims by the current king, the function contains an inverted require condition that mistakenly permits only the current king to call claimThrone(). As a result, all new claim attempts revert, effectively preventing any player from participating and blocking game progression..

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

Risk

Likelihood:

  • This will occur when a new player, who is not the current king, attempts to claim the throne at any point during the game. It also consistently prevents the game from even starting since the initial currentKing is address(0) and no one else can claim.

Impact:

  • The game becomes completely non-functional as no player can successfully claim the throne. This results in the pot never accumulating and all core game mechanics being rendered unusable.

Proof of Concept

The following Foundry test demonstrates that a valid new player is unable to claim the throne due to the inverted logic in the require condition.

// This test proves that new players cannot claim the throne due to incorrect access control
function test__withdrawFunds() public {
// Ensure initial king is address(0)
assertEq(game.currentKing(), address(0));
// Simulate player1 trying to claim the throne
console2.log(player1);
vm.prank(player1);
// Expect revert with the current (buggy) require string
vm.expectRevert("Game: You are already the king. No need to re-claim.");
game.claimThrone{value: 1 ether}();
}

Recommended Mitigation

To fix this issue, simply invert the condition in the require statement so that it blocks reclaims by the current king, rather than allowing only the king to call the function:

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