Emiting zero prizeAmount/pot value when declare winner
Description
In expected behavior prizeAmount/pot value in emiting event will reveal The total prize amount won
, but in the function Game::declareWinner
emit prizeAmount/pot didn't work as expected, the issue is in the #L241
.
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);
}
Risk
Likelihood:
Impact:
Proof of Concept
Here's the test by emiting expected event
function test_DeclareWinnerAndEmitGameEnded() public {
vm.startPrank(player1);
game.claimThrone{value: game.claimFee()}();
uint256 gracePeriodEnd = block.timestamp + GRACE_PERIOD + 1;
vm.warp(gracePeriodEnd);
vm.expectEmit(true, false, false, true);
emit GameEnded(player1, game.pot(), gracePeriodEnd, 1);
game.declareWinner();
vm.stopPrank();
}
and this the log from the test:
[227539] GameTest::test_DeclareWinnerAndEmitGameEnded()
├─ [0] VM::startPrank(player1: [0x7026B763CBE7d4E72049EA67E89326432a50ef84])
│ └─ ← [Return]
├─ [2514] Game::claimFee() [staticcall]
│ └─ ← [Return] 100000000000000000 [1e17]
├─ [150621] Game::claimThrone{value: 100000000000000000}()
│ ├─ emit ThroneClaimed(newKing: player1: [0x7026B763CBE7d4E72049EA67E89326432a50ef84], claimAmount: 100000000000000000 [1e17], newClaimFee: 110000000000000000 [1.1e17], newPot: 95000000000000000 [9.5e16], timestamp: 1)
│ └─ ← [Stop]
├─ [0] VM::warp(86402 [8.64e4])
│ └─ ← [Return]
├─ [0] VM::expectEmit(true, false, false, true)
│ └─ ← [Return]
├─ [515] Game::pot() [staticcall]
│ └─ ← [Return] 95000000000000000 [9.5e16]
├─ emit GameEnded(winner: player1: [0x7026B763CBE7d4E72049EA67E89326432a50ef84], prizeAmount: 95000000000000000 [9.5e16], timestamp: 86402 [8.64e4], round: 1)
├─ [50689] Game::declareWinner()
│ ├─ emit GameEnded(winner: player1: [0x7026B763CBE7d4E72049EA67E89326432a50ef84], prizeAmount: 0, timestamp: 86402 [8.64e4], round: 1)
│ └─ ← [Stop]
└─ ← [Revert] log != expected log
as you can see there's missmatch from expected event prizeAmount and the actual happen in Game::declareWinner
function.
Recommended Mitigation
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;
+ emit GameEnded(currentKing, pot, block.timestamp, gameRound);
- pot = 0; // Reset pot after assigning to winner's pending winnings
- emit GameEnded(currentKing, pot, block.timestamp, gameRound);
+ pot = 0; // Reset pot after assigning to winner's pending winnings
}
place updated pot after emiting the event.