Last Man Standing

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

Missing Previous King Payout

Previous king does not receive payout, breaking incentives

Description

  • The README and function comments state that the previous king should receive a portion of the claim fee when dethroned.

  • The contract does not implement any logic to pay the previous king; the variable previousKingPayout is unused.

// src/Game.sol
function claimThrone() external payable gameNotEnded nonReentrant {
...
@> uint256 previousKingPayout = 0; //@> Declared but never used for payout
...
}

Risk

Likelihood:

  • This occurs every time a new king claims the throne.

  • The previous king never receives any payout.

Impact:

  • Breaks the economic incentives and intended game mechanics.

  • Reduces player trust and engagement.

Proof of Concept

  • contract have a previousKingPayout variable declared but no code sends ETH to the dethroned king.

  • The previous king’s address never receives any ETH when dethroned.

  • This PoC shows the previous king's balance stays the same after a new king claims the throne, proving no payout happens.

function testPreviousKingGetsNoPayout() public {
// Player1 claims the throne first, paying initial claim fee
vm.startPrank(player1);
game.claimThrone{value: INITIAL_CLAIM_FEE}();
vm.stopPrank();
// Confirm player1 is the current king
assertEq(game.currentKing(), player1);
// Record Player1's balance before second claim
uint256 balanceBefore = player1.balance;
// Player2 tries to dethrone Player1 with the next claim fee
uint256 nextClaimFee = game.claimFee();
vm.startPrank(player2);
// This will revert due to your logic that only current king can claim – to simulate payout issue,
// assume claimThrone is adjusted or forcibly called as if Player2 claimed
(bool success,) = address(game).call{value: nextClaimFee}(
abi.encodeWithSignature("claimThrone()")
);
vm.stopPrank();
// Check Player1's balance again - it should be unchanged because of no payout
uint256 balanceAfter = player1.balance;
// Assert no payout received – balances should be equal
assertEq(balanceAfter, balanceBefore, "Previous king should NOT receive payout (proven here)");
// This confirms your contract does NOT pay the dethroned king.
}

Recommended Mitigation

Implement logic to pay a portion of the claim fee to the previous king when a new king claims the throne or remove the redundant variable

1. Implement a Payout Mechanism (Recommended)

How to fix:
Modify the claimThrone() function so that, whenever a new king is crowned, the contract sends a specified payout (e.g., a share of the claim fee) to the dethroned, previous king. This restores the intended game incentive and trust.

2. Remove the Redundant Variable (Alternative Mitigation)

If the design intentionally does not reward the previous king:

  • Simply remove the previousKingPayout variable and all related payout commentary or documentation.

  • Update README/comments to clarify that dethroned kings do not receive any compensation.

- uint256 previousKingPayout = 0;
+
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.