Last Man Standing

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

[H-01] Incorrect require condition in claimThrone() prevents new players from claiming the throne

Root + Impact

  • No player can ever claim the throne unless they are already the king.

  • This breaks the core functionality of the game and makes it unplayable.

  • It also means that no one can win the prize pot, defeating the purpose of the contract.

Description

The claimThrone() function is designed to allow a new player to become the currentKing by paying a required fee. However, the condition that checks whether the caller is already the king is written incorrectly, preventing anyone from claiming the throne unless they are already the king — which breaks the core game mechanic.

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.");
uint256 sentAmount = msg.value;
uint256 previousKingPayout = 0;
uint256 currentPlatformFee = 0;
uint256 amountToPot = 0;
// Calculate platform fee
currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
// Defensive check to ensure platformFee doesn't exceed available amount after previousKingPayout
if (currentPlatformFee > (sentAmount - previousKingPayout)) {
currentPlatformFee = sentAmount - previousKingPayout;
}
platformFeesBalance = platformFeesBalance + currentPlatformFee;
// Remaining amount goes to the pot
amountToPot = sentAmount - currentPlatformFee;
pot = pot + amountToPot;
// Update game state
currentKing = msg.sender;
lastClaimTime = block.timestamp;
playerClaimCount[msg.sender] = playerClaimCount[msg.sender] + 1;
totalClaims = totalClaims + 1;
// Increase the claim fee for the next player
claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100;
emit ThroneClaimed(
msg.sender,
sentAmount,
claimFee,
pot,
block.timestamp
);
}

Risk

Likelihood:

  • Reason 1 if accures when a player calls claimThrone

  • Reason 2 Only king can call claim throne

Impact:

  • Impact 1 No player can ever claim the throne unless they are already the king.

  • Impact 2 This breaks the core functionality of the game and makes it unplayable

Proof of Concept

function testClaimThrone() public {
vm.startPrank(player2);
game.claimThrone{value: INITIAL_CLAIM_FEE}();
vm.stopPrank();
assertEq(game.currentKing(), player2);
}

Test Result

Failing tests:
Encountered 1 failing test in test/Game.t.sol:GameTest
[FAIL: Game: You are already the king. No need to re-claim.] testClaimThrone() (gas: 46372)
Encountered a total of 1 failing tests, 0 tests succeeded

it reverts with u are already the king

Recommended Mitigation

- (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 17 days 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.