Last Man Standing

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

Missing Previous King Payout Breaks Incentive Structure

The `claimThrone()` function fails to compensate the previous king after being dethroned. Although the game logic implies that the previous king should receive a portion of the next claim's ETH, no such payout occurs. This breaks the incentive mechanism and discourages strategic early participation.

Description

In a “Last Man Standing” game, dethroned kings are typically rewarded with part of the next claim fee. This keeps players engaged and encourages early claims.

The contract defines a variable previousKingPayout = 0, implying a reward for the former king.

However, no ETH is ever calculated or transferred to the dethroned king, and the variable is left unused.

This leads to a situation where only the pot and platform owner benefit, while the dethroned king receives nothing — breaking the game’s intended fairness and reward cycle.

This leads to a situation where only the pot and platform owner benefit, while the dethroned king receives nothing — breaking the game’s intended fairness and reward cycle.

function claimThrone() external payable gameNotEnded nonReentrant {
...
uint256 previousKingPayout = 0;
@> // payout calculation missing, nothing is sent to the old king
...
}

Risk

Likelihood:

This happens consistently on every claim after the first one.

All dethroned kings receive no rewards, despite being key participants in gameplay progression.

Impact:

Disincentivizes early players from participating due to guaranteed loss if dethroned.

Undermines trust and fairness in the protocol.

Results in reduced user engagement and participation, harming the protocol’s growth and adoption.

Proof Of Concept

// Alice becomes the first king
game.claimThrone{value: game.claimFee()}({from: Alice}); // ✅ Success
// Bob dethrones Alice
game.claimThrone{value: game.claimFee()}({from: Bob}); // ✅ Success
// Alice checks for payout
assert(pendingWinnings[Alice] == 0); // ❌ Should have received part of Bob's claimFee

Explanation:
The previousKingPayout variable is defined but never used to allocate funds to the dethroned king. This breaks the expected economic model and discourages further participation.

Recommended Mitigation

+ if (currentKing != address(0)) {
+ uint256 previousKingPayout = (sentAmount * 10) / 100; // 10% to dethroned king
+ pendingWinnings[currentKing] += previousKingPayout;
+ sentAmount -= previousKingPayout;
+ }
- uint256 previousKingPayout = 0; // remove unused variable

Explanation:
This change allocates 10% of the claim fee to the dethroned king via pendingWinnings, preserving player incentives and fairness. This aligns with the expected competitive and rewarding nature of a king-of-the-hill game.

Updates

Appeal created

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