Last Man Standing

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

Previous King Not Rewarded Despite Documentation Claims

Summary

The contract documentation states that previous kings receive a portion of new claim fees, but no such mechanism is implemented, creating a discrepancy between expected and actual behavior.

Description

The claimThrone() function's natspec comment claims: "If there's a previous king, a small portion of the new claim fee is sent to them." However, the code calculates previousKingPayout = 0 and never implements any reward mechanism for displaced kings.

Root Cause

The previousKingPayout variable is initialized to 0 and never modified, despite being referenced in calculations. No code exists to:

  • Calculate the previous king's reward

  • Transfer funds to the previous king

  • Update their pending winnings

Impact

  • Trust Issues: Users expect previous kings to be rewarded based on documentation

  • Economic Loss: Previous kings lose their investment without any compensation

  • Unfair Game Mechanics: Only the final winner receives rewards, making early participation economically irrational

Proof of Concept

function testPreviousKingDoesntGetRewarded() public {
uint256 claimFee = INITIAL\_CLAIM\_FEE;
uint256 player1InitialBalance = player1.balance;
// Player1 claims throne
vm.prank(player1);
game.claimThrone{value: claimFee}();
uint256 player1BalanceAfterClaim = player1.balance;
assertEq(player1BalanceAfterClaim, player1InitialBalance - claimFee);
// Calculate next claim fee
uint256 nextClaimFee = claimFee + (claimFee * FEE_INCREASE_PERCENTAGE) / 100;
// Player2 claims throne (displacing player1)
vm.prank(player2);
game.claimThrone{value: nextClaimFee}();
// Player1 balance unchanged (no reward received)
assertEq(player1.balance, player1BalanceAfterClaim);
// Verify player1 has no pending winnings
assertEq(game.pendingWinnings(player1), 0);
}

Recommended Mitigation

Either implement the promised reward mechanism or update the documentation:

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;
// Reward previous king if exists
if (currentKing != address(0)) {
previousKingPayout = (sentAmount * 10) / 100; // 10% to previous king
pendingWinnings[currentKing] += previousKingPayout;
}
uint256 currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
uint256 amountToPot = sentAmount - previousKingPayout - currentPlatformFee;
platformFeesBalance += currentPlatformFee;
pot += amountToPot;
// Rest of function...
}
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!