Last Man Standing

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

Discrepancy Between Documentation and Implementation Regarding Previous King Payout

Root + Impact

Description

  • The claimThrone() function’s documentation states that the previous king receives a portion of the new claim fee, but the implementation does not execute this logic. Instead, it initializes previousKingPayout = 0 and never assigns any value to it, meaning the previous king receives nothing.

  • The defensive check (if (currentPlatformFee > (sentAmount - previousKingPayout))) is redundant since previousKingPayout is always 0.

// Root cause in the codebase with @> marks to highlight the relevant section
​
/**
* @dev Allows a player to claim the throne by sending the required claim fee.
* If there's a previous king, a small portion of the new claim fee is sent to them.
* A portion also goes to the platform owner, and the rest adds to the pot.
*/
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;
​
// 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;
}
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: Medium

  • Reason 1 : The discrepancy affects every throne claim after the first one (i.e., whenever there is a previous king).

  • Reason 2: The mismatch between docs and code guarantees user confusion, as the promised payout mechanism is non-functional.

Impact:

  • Impact 1: Economic distortion – The pot grows larger than intended (since no funds are diverted to previous kings), unfairly benefiting future winners.

  • Impact 2: Reputational harm.

Proof of Concept

  1. Scenario:

    • Player1 claims the throne (becomes currentKing).

    • Player2 claims the throne, sending 1 ETH (claimFee = 1 ETH).

    • Expected: Player1 (previous king) receives a small payout (e.g., 10%).

    • Actual: Player1 receives nothing; entire 1 ETH (minus platform fee) goes to the pot.

​

Recommended Mitigation

1.Implement the payout logic to match the docs.

2.Or Update the documentation to remove references to previous king payouts.


Updates

Appeal created

inallhonesty Lead Judge about 1 year 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.

Give us feedback!