Last Man Standing

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

No Incentive Given to Previous King Despite Stated Game Rules

No Incentive Given to Previous King Despite Stated Game Rules

Description

  • In the game's expected behavior, the previous king (i.e., the player dethroned by the latest claimer) should receive a small incentive from the next player's claim fee.

  • However, in the current implementation of claimThrone(), no incentive is given to the previous king, despite this being clearly documented in the game’s rules.

  • This creates a mismatch between documentation and smart contract logic, and may break trust or cause disputes among users.

  • And also Dead logic due to previousKingPayout =0 because currentPlatformFee is certain percentage of sentAmount and
    it never greater and also also even previousKingPayout =1 then also sentAmount - previousKingPayout means also definitly

    if (currentPlatformFee > (sentAmount - previousKingPayout)) is false

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; // @> Hardcoded to zero
uint256 currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
if (currentPlatformFee > (sentAmount - previousKingPayout)) {
currentPlatformFee = sentAmount - previousKingPayout; // @> Dead logic due to previousKingPayout = 0
}
platformFeesBalance = platformFeesBalance + currentPlatformFee;
uint256 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;
}

Risk

Likelihood:

  • This issue will always occur when a new player claims the throne, because the code never assigns a non-zero value to previousKingPayout.

  • Game participants expecting a reward based on documentation will never receive it, which can discourage participation or lead to loss of user trust.

  • Since the game is expected to pay out rewards to dethroned players (as stated in the rules), the discrepancy is guaranteed to be noticed in real deployments.

Impact:

  • The previous king receives no payout, contradicting the advertised rules.

  • This may lead to:

    • Players feeling cheated or misled.

    • Reduced participation or complaints from users.

    • Centralization of benefit to the platform owner, who still receives fees as intended.

Proof of Concept

// Assume initialClaimFee = 10 ETH, platformFee = 10%
// A claims throne (no issue)
game.claimThrone{value: 10 ether}(); // A becomes king
// B claims throne with 12 ETH
game.claimThrone{value: 12 ether}(); // A expects payout but receives nothing
// Inspect pendingWinnings[A] => 0
assert(game.pendingWinnings(A) == 0); // Should be non-zero

Recommended Mitigation


Add logic to reward the previous king with a percentage (e.g., 10%) of the incoming claim fee:
- uint256 previousKingPayout = 0;
+ uint256 previousKingPayout = 0;
+ if (currentKing != address(0)) {
+ previousKingPayout = (sentAmount * 10) / 100;
+ pendingWinnings[currentKing] += previousKingPayout;
+ }
uint256 currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
Updates

Appeal created

inallhonesty Lead Judge about 2 months 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.