Last Man Standing

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

Missing Payout to Previous King in claimThrone()

Root + Impact

Description

  • The contract explicitly states in the "King (Current King)" actor definition: "Receives a small payout from the next player's claimFee (if applicable)."

  • The claimThrone() function fails to pay out the intended portion of the claimFee to the previous king, leading to unjust enrichment of the game's pot or platform fees, and direct financial loss for the previous king, as the logic for calculating and transferring this payout is entirely absent from the code.


In src/Game.sol, within the claimThrone() function, the variable previousKingPayout is explicitly initialized to 0 and is never updated with any calculation based on the sentAmount or claimFee. Consequently, no msg.sender.transfer() or similar mechanism is ever called to send a portion of the incoming fee to the currentKing (who is about to become the previousKing). This contradicts the described game mechanic where the current King should receive a payout from the next claimant. All funds that should have gone to the previous king are instead added to the pot or platformFeesBalance.

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;
uint256 currentPlatformFee = 0;
uint256 amountToPot = 0;
// Calculate platform fee
currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
// Defensive check to ensure platformFee doesn't exceed available amount after previousKingPayout
if (currentPlatformFee > (sentAmount - previousKingPayout)) {
currentPlatformFee = sentAmount - previousKingPayout;
}
platformFeesBalance = platformFeesBalance + currentPlatformFee;
// Remaining amount goes to the pot
amountToPot = sentAmount - currentPlatformFee;
pot = pot + amountToPot;
// Update game state
currentKing = msg.sender;
lastClaimTime = block.timestamp;
playerClaimCount[msg.sender] = playerClaimCount[msg.sender] + 1;
totalClaims = totalClaims + 1;
// Increase the claim fee for the next player
claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100;
emit ThroneClaimed(
msg.sender,
sentAmount,
claimFee,
pot,
block.timestamp
);
}

Risk

Likelihood: This issue is highly likely to occur because the flaw is inherent in the function's logic and will trigger every single time a new player claims the throne (after the very first king has been established). The code explicitly sets previousKingPayout to 0 and has no mechanism to calculate or send this payout, meaning the described game mechanic for previous kings' earnings will never function as intended.

Impact:

  • Direct Financial Loss (for Previous King): The currentKing who is dethroned does not receive the "small payout from the next player's claimFee" as described in the game's rules. This is a direct financial loss for a legitimate actor.

  • The game's core rule regarding the previous king's payout is not implemented, breaking the stated functionality and user expectations.

Proof of Concept

Recommended Mitigation

The claimThrone() function needs to implement the logic for calculating the previous King's payout and transferring that amount to them before updating currentKing.
Proposed Solution:
Store previousKing: A local variable should capture the currentKing before it's updated.
Calculate Payout: Define a specific payoutPercentage (or fixed amount) for the previous king. This parameter would likely need to be added to the contract's state and initialized by the owner.
Perform Transfer: Execute a transfer or call to send the previousKingPayout amount to the previousKing address.
Adjust Pot Calculation: Ensure the amount added to the pot correctly subtracts both the platformFee and the previousKingPayout.
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.