Last Man Standing

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

Inverted Logic in `claimThrone` Prevents New Players from Taking Throne

Description

  • The claimThrone function should allow new players to overthrow the current king by paying the required claim fee, implementing the core "king of the hill" game mechanic.

  • The function contains inverted logic that only allows the current king to claim the throne again, preventing any new players from participating after the first claim.

function claimThrone() external payable gameNotEnded nonReentrant {
require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
// @> This logic is inverted - only current king can proceed
require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim.");
// Game state updates...
}

Risk

Likelihood:

  • After the first successful claim, all subsequent claims by different players will revert

  • Every new player transaction will fail at the second require statement

Impact:

  • Game becomes permanently stuck with the first king

  • Core "king of the hill" mechanic is completely non-functional

  • Contract becomes economically useless after first interaction

  • All future participants are locked out of the game

Proof of Concept

  1. Player A calls claimThrone() and becomes the first king (currentKing = Player A)

  2. Player B tries to claim throne with sufficient ETH

  3. Transaction fails at require(msg.sender == currentKing) because Player B ≠ Player A

  4. Only Player A can call claimThrone() again, but error message contradicts this

  5. Game is permanently broken

require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim.");
// Logic: If sender IS current king → allow (but error message suggests prevent)
// Reality: Only current king can proceed, contradicting the error message

Recommended Mitigation

Fix the inverted logic:

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.");
+ require(msg.sender != currentKing, "Game: You are already the king. No need to re-claim.");
// This allows new players to claim while preventing current king from re-claiming
}
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.