Last Man Standing

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

Missing previous king payout - reward mechanism is broken

Missing previous king payout - reward mechanism is broken

Description

When a new player claims the throne, a small portion of the claim fee is intended to be paid to the previous king as an incentive for participation. However, the previousKingPayout is always initialized and left at 0, meaning no funds are never reserved for the former king - even though the code intends to support this mechanic.

function claimThrone() external payable gameNotEnded nonReentrant {
...
@> uint256 previousKingPayout = 0;
....
// Defensive check to ensure platformFee doesn't exceed available amount after previousKingPayout
@> if (currentPlatformFee > (sentAmount - previousKingPayout)) {
@> currentPlatformFee = sentAmount - previousKingPayout;
}

Risk

Likelihood: High

This happens every time a new player claims the throne.

Impact: Medium

The previous king receives no payout, reducing game incentives.

Proof of Concept

function test_previousKingDoesNotGetPayout() public {
vm.prank(player1);
game.claimThrone{value: INITIAL_CLAIM_FEE}();
assertEq(game.currentKing(), player1, "Player1 should be the current king");
assertEq(game.pendingWinnings(player1), 0, "Player1 should not have pending winnings");
uint256 claimFee = game.claimFee();
vm.prank(player2);
game.claimThrone{value: claimFee}();
assertEq(game.currentKing(), player2, "Player2 should be the current king");
assertEq(game.pendingWinnings(player2), 0, "Player2 should not have pending winnings");
assertEq(game.pendingWinnings(player1), 0, "Player1 should have pending winnings as previous king payout");
vm.warp(block.timestamp + game.gracePeriod() + 1);
vm.prank(player3);
game.declareWinner();
assertEq(game.currentKing(), player2, "Player2 should be the current king");
uint256 kingExpectedWinnings = claimFee + INITIAL_CLAIM_FEE - game.platformFeesBalance();
assertEq(game.pendingWinnings(player2), kingExpectedWinnings, "Player2 should not have pending winnings");
assertEq(game.pendingWinnings(player1), 0, "Player1 should have pending winnings as previous king payout");
}

According to documentation, the pendingWinnings data structure stores kings and previous kings balances.

Recommended Mitigation

Calculate the previous king payout and include it in the expected data structure.

- uint256 previousKingPayout = 0;
+ uint256 previousKingPayout = previousKingPayoutFormula();
...
+ pendingWinnings[previousKing] += previousKingPayout;
Updates

Appeal created

inallhonesty Lead Judge 4 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.

Give us feedback!