Last Man Standing

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

Incorrect `prizeAmount` in `GameEnded` Event

Description:
Inside declareWinner(), the code zeroes out pot before emitting the GameEnded event, causing the event’s prizeAmount field to always be reported as 0.

Impact: This creates incorrect event logs that could mislead external systems, frontends, or analytics tools about the actual prize amounts won.

  • Misleading Analytics: Off-chain services and UIs will believe the winner received 0 ETH.

  • Data Integrity: Historical data on game outcomes is corrupted.

Proof of Concept: Add the following test to the 'Game.t.sol':

function testGameEndedEventPrizeIsZero() public {
// Would need to fix the contract first (incorrect king validation logic), but this demonstrates the vulnerability
// player1 becomes king
vm.prank(player1);
game.claimThrone{value: INITIAL_CLAIM_FEE}();
// Simulate end of game
vm.warp(block.timestamp + 2 days);
vm.expectEmit(true, true, true, true);
emit Game.GameEnded(player1, 0, block.timestamp, 1);
game.declareWinner();
}

Mitigation:
Capture pot in a local variable before resetting:

function declareWinner() external gameNotEnded {
require(currentKing != address(0), "Game: No one has claimed the throne yet.");
require(block.timestamp > lastClaimTime + gracePeriod, "Game: Grace period has not expired yet.");
gameEnded = true;
- pendingWinnings[currentKing] = pendingWinnings[currentKing] + pot;
- pot = 0;
+ uint256 prize = pot;
+ pendingWinnings[currentKing] += prize;
+ pot = 0;
emit GameEnded(currentKing, prize, block.timestamp, gameRound);
}
Updates

Appeal created

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Game::declareWinner emits GameEnded event with pot = 0 always

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!