Last Man Standing

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

In claimeThrone() there is no logic to compensate the previous king when a new player claims the throne.

Root + Impact

Description

  • According to the game documentation: "The current king receives a small payout from the next player's claimFee (if applicable)."

  • However, in the current implementation of the claimThrone() function, there is no logic to compensate the previous king when a new player claims the throne. The variable previousKingPayout is declared but never assigned or used.

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; // @> Declared but unused
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; // @> Irrelevant since previousKingPayout is 0
}
}
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:

  • The issue will occur every time a new player claims the throne, because previousKingPayout is always set to 0 and never update.

  • The documentation clearly states the previous king should receive a portion of the claim fee - but no logic implements this behavior.

Impact:

  • Players expect to earn partial rewards when dethroned, which is a core mechanic and incentive.

  • Previous kings never receive compensation, making the game less attractive and possibly discouraging participation.

  • Reputational risk for the contract owner if the siscrepancy between doc and logic is discovered post-deployement

Proof of Concept

  1. Player 1 calls `claimThrone()` and becomes the current king

  2. Player 2 calls `claimThrone()` with sufficient ETH

  3. Player 1 receives nothing, despite being promised a reward. But he should received a small reward as per documentation.

Recommended Mitigation

Implement payout logic for the previous king in claimThrone()

+ if (currentKing != address(0)) {
+ previousKingPayout = (sentAmount * previousKingRewardPercentage) / 100;
+ pendingWinnings[currentKing] += previousKingPayout;
+ }
currentPlatformFee+ = (sentAmount * platformFeePercentage) / 100;
if (currentPlatformFee > (sentAmount - previousKingPayout)) {
currentPlatformFee = sentAmount - previousKingPayout;
}
platformFeesBalance += currentPlatformFee;
+ amountToPot = sentAmount - previousKingPayout - currentPlatformFee;
pot += amountToPot;
Updates

Appeal created

inallhonesty Lead Judge 11 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Missing Previous King Payout Functionality

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.