Root Cause
The pot
variable is being reset to 0 before the GameEnded
event is emitted.
Since Solidity evaluates arguments at the time of emit
, the value of pot
passed to the event is 0
, even though the actual prize was transferred correctly.
Vulnerable Function
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;
@> emit GameEnded(currentKing, pot, block.timestamp, gameRound);
}
Impact
-
Incorrect event data: The GameEnded
event always emits 0
as the prize amount.
-
Off-chain consumers (frontends, analytics, The Graph) will show misleading or wrong winner payouts.
-
May break trust or external integrations relying on accurate event logs.
Proof of Concept (PoC)
event GameEnded(address indexed winner, uint256 prizeAmount, uint256 timestamp, uint256 round);
function test_GameEndedEmitsInCorrectPrizeAmount() public {
vm.startPrank(player1);
game.claimThrone{value: game.claimFee()}();
vm.warp(block.timestamp + game.gracePeriod() + 1);
vm.expectEmit(true, false, false, false);
emit GameEnded(game.currentKing(), game.pot(), block.timestamp, game.gameRound());
game.declareWinner();
}
Recommended Mitigation:
Store the pot
in a temporary variable before modifying it, and use that in both logic and event emission:
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;
uint256 prizeAmount = pot;
pendingWinnings[currentKing] = pendingWinnings[currentKing] + prizeAmount;
pot = 0;
emit GameEnded(currentKing, prizeAmount, block.timestamp, gameRound);
}
Severity: Low
-
It doesn't affect funds or security.
-
But it does affect off-chain trust, data accuracy, and external integrations.