Last Man Standing

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

Cannot call `declareWinner()` after `gracePeriod` has passed

Description

player1 claims the throne half a day after the game starts, so there should be only half a day left to call declareWinner().

However, after 0.75 days (three-quarters of a day), when player1 tries to declare the winner, they're surprised that the game has not ended yet.

Proof of Concept

But before running the test, you need to correct this issue in claimThrone():

- require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim.");
+ require(msg.sender != currentKing, "Game: You are already the king. No need to re-claim.");

Add this test to Game.t.sol:

function testdeclareWinner() public {
vm.warp(block.timestamp + 0.5 days); // half a day later
vm.startPrank(player1);
game.claimThrone{value: 0.1 ether}();
vm.stopPrank();
vm.warp(block.timestamp + 0.75 days); // three-quarters of a day later
vm.startPrank(player1);
game.declareWinner();
vm.stopPrank();
}

This will throw:
"Grace period has not expired yet."

Recommended Mitigation

Use the fixed startGame timestamp instead of lastClaimTime to check if the grace period has passed:

+ uint256 public startGame;
...
require(
+ block.timestamp > startGame + gracePeriod,
- block.timestamp > lastClaimTime + gracePeriod,
"Game: Grace period has not expired yet."
);

This ensures the game ends relative to when it started not based on throne claims.

Updates

Appeal created

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

declareWinner time check is not properly done

Support

FAQs

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