Last Man Standing

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

Next user can claim the throne with less `claimFee` than the `currentKing`

Description

The mechanism of this game is: if no one pays more fees than you during the gracePeriod, you will win the pot prize as the last currentKing.

If player1 pays a higher fee (0.4 ether) to claim the throne and increase his chances of staying king, and then player2 comes afterward and wants to claim the throne, the required claim fee becomes only (0.11 ether). He pays it and becomes the currentKing instead of player1.

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.");

Then, add this test to Game.t.sol:

function testclaimThrone3() public {
vm.startPrank(player1);
game.claimThrone{value: 0.4 ether}();
vm.stopPrank();
console2.log("currentKing:", game.currentKing());
vm.startPrank(player2);
game.claimThrone{value: 0.11 ether}();
vm.stopPrank();
console2.log("currentKing:", game.currentKing());
}

Then run:
forge test --match-test testclaimThrone3 -vv
And this will pass

Recommended Mitigation

You need to update the claim fee to depend on how much the currentKing paid,
rather than using a constant percentage increase.

+ claimFee = msg.value + (msg.value * feeIncreasePercentage) / 100;
- claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100;

or
just prevent user to claimThrone with extra fee

- require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
+ require(msg.value = claimFee, "Game: Insufficient ETH sent to claim the throne.");
Updates

Appeal created

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

Overpayment not refunded, included in pot, but not in claim fee

Support

FAQs

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