Last Man Standing

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

Incorrect Throne Claim Logic Allows No One to Ever Become King

Root + Impact

Description

  • In normal behavior, any player should be able to claim the throne by sending the required claimFee in ETH. This action updates the currentKing, adds funds to the prize pot, increases the claimFee, and resets the gracePeriod timer

  • The issue is that the contract contains a faulty condition in the claimThrone() function that only allows the current king to claim the throne again. Since the currentKing starts as address(0), no one can claim the throne, and the game becomes permanently locked and unusabl

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

Risk

Likelihood:

  • The issue occurs immediately after deployment. No user is able to call claimThrone() successfully unless they are address(0), which is not a normal externally owned account (EOA).

  • As a result, the game is locked in an unusable state forever unless the contract is manually reset or modified.

Impact:

  • No player can ever claim the throne.

  • The clainFee, pot, and reward logic are never triggered.

  • The game is permanently disabled, and any ETH sent may become stuck.

Proof of Concept

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/Game.sol";
contract PoCTest is Test {
Game game;
address alice = address(0x1234);
function setUp() public {
// Deploy the Game contract with valid parameters
game = new Game(
0.01 ether, // initialClaimFee
3 days, // gracePeriod
15, // feeIncreasePercentage
3 // platformFeePercentage
);
}
function testClaimThroneFailsDueToIncorrectRequire() public {
// Simulate Alice trying to claim the throne
vm.deal(alice, 1 ether); // Fund Alice with ETH
vm.prank(alice);
// Expect revert due to incorrect logic in require()
vm.expectRevert(bytes("Game: You are already the king. No need to re-claim."));
game.claimThrone{value: 0.02 ether}(); // Attempt to claim throne fails
}
}

Recommended Mitigation

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