Game::claimThrone
has a require that blocks all players from participating
Description
The claimThrone()
function should allow any player to claim the throne if they pay the claimFee and are not the current king. This is essential to start and continue the game.
Currently, there is a misformulated require that prevents any player from participating, even in the first round. The initial currentKing
is address(0)
, so no player can pass the require, leaving the game completely unusable.
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;
currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
if (currentPlatformFee > (sentAmount - previousKingPayout)) {
currentPlatformFee = sentAmount - previousKingPayout;
}
platformFeesBalance = platformFeesBalance + currentPlatformFee;
amountToPot = sentAmount - currentPlatformFee;
pot = pot + amountToPot;
currentKing = msg.sender;
lastClaimTime = block.timestamp;
playerClaimCount[msg.sender] = playerClaimCount[msg.sender] + 1;
totalClaims = totalClaims + 1;
claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100;
emit ThroneClaimed(
msg.sender,
sentAmount,
claimFee,
pot,
block.timestamp
);
}
Risk
Likelihood: High
Impact: High
-
No player can start the game.
-
The contract becomes unusable, completely blocking the main functionality.
Proof of Concept
Reverts whenever anyone tries to claim the throne due to the misformulated require that blocks all participation.
function test_AnyPlayerCanClaimThrone() public {
vm.startPrank(player1);
vm.expectRevert("Game: You are already the king. No need to re-claim.");
game.claimThrone{value: INITIAL_CLAIM_FEE}();
}
Ran 1 test for test/Game.t.sol:GameTest
[PASS] test_AnyPlayerCanClaimThrone() (gas: 46937)
Recommended Mitigation
Fix the condition so that only the current king cannot claim, but any other player can start or participate in the game.
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.");
uint256 sentAmount = msg.value;
uint256 previousKingPayout = 0;
uint256 currentPlatformFee = 0;
uint256 amountToPot = 0;
....