Description:
The Game::claimThrone()
function contains an incorrect logic check:
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.");
}
This condition incorrectly restricts the ability to claim the throne to the currentKing
only, which defeats the purpose of the game where new players should be able to challenge and claim the throne by paying the required fee. This results in the game being in a permanently blocked state after deployment.
Impact: HIGH
-
No player can successfully call claimThrone()
, rendering the game non-functional.
-
The currentKing remains address(0), so no winner can be declared.
-
The game is in a blocked state from the beginning.
Proof of Concept:
function testNoOneCanClaimTheThrone() public {
console.log("Current king is", game.currentKing());
vm.startPrank(player1);
uint256 amount = 10 ether;
vm.expectRevert("Game: You are already the king. No need to re-claim.");
game.claimThrone{value: amount}();
}
[PASS] testNoOneCanClaimTheThrone() (gas: 50563)
Logs:
Current king is 0x0000000000000000000000000000000000000000
Traces:
[50563] GameTest::testNoOneCanClaimTheThrone()
├─ [2446] 0x8Ad159a275AEE56fb2334DBb69036E9c7baCEe9b::currentKing() [staticcall]
│ └─ ← [Return] 0x0000000000000000000000000000000000000000
├─ [0] console::log("Current king is", 0x0000000000000000000000000000000000000000) [staticcall]
│ └─ ← [Stop]
├─ [0] VM::startPrank(player1: [0x7026B763CBE7d4E72049EA67E89326432a50ef84])
│ └─ ← [Return]
├─ [0] VM::expectRevert(custom error 0xf28dceb3: Game: You are already the king. No need to re-claim.)
│ └─ ← [Return]
├─ [26959] 0x8Ad159a275AEE56fb2334DBb69036E9c7baCEe9b::claimThrone{value: 10000000000000000000}()
│ └─ ← [Revert] revert: Game: You are already the king. No need to re-claim.
└─ ← [Stop]
Recommended Mitigation:
Update the claim logic to prevent the current king from re-claiming, while allowing new challengers to participate.
function claimThrone() external payable gameNotEnded nonReentrant {
- 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.");
}