Description
The claimThrone() function claims that, if there is a previous king, a portion of the new claim fee will be sent to them. However, in the actual implementation, no payout is made to the previous king at any point.
Although the documentation suggests a reward mechanism for the dethroned player, the contract neither calculates nor transfers any amount to the previous king. The variable previousKingPayout is initialized to zero and never updated, and no previousKing address is stored or used.
This results in a functional inconsistency where dethroned kings receive no ETH, despite expectations set by the documentation and comments.
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 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
);
}
Impact:
Players who lose the throne receive no compensation, even though the documentation implies they should. This may lead to confusion, reduced trust in the game logic, and a poor user experience.
Recommended Mitigation
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;
+ address previousKing = currentKing;
// Calculate platform fee
currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
// calculate pervious king fee
+ previousKingPayout = (sentAmount * previousKingRewardPercentage) / 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 - previousKingPayout;
+ pot = pot + amountToPot;
+
+ // Send reward to previous king
+ if (previousKing != address(0)) {
+ pendingWinnings[previousKing] += previousKingPayout;
+ }else {
+ pot = pot + previousKingPayout;
}
// 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
);
}