Eggstravaganza

First Flight #37
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Invalid

Game owner can mint as much as wants with threshold manipulation

Summary

After game starts, using EggHuntGame::setEggFindThreshold(100) Owner can increase chance for himself to 100% and win the Egg every time he plays. There must exist some restriction in which Owner doesn't have that kind of unlimited advantage because game is unplayable if owner plays.

Vulnerability Details

Since the owner has no restrictions and can play the game just like the players, it is possible for him to increase his chances by changing EggHuntGame::eggFindThreshold to 100 every time he wants to play. Then, afterward, he can run EggHuntGame::searchForEgg multiple times and win an Egg every time because:

uint256 random = uint256(
keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender, eggCounter))
) % 100;

will always be less than 100.

Proof of concept

  1. Owner creates and starts a game.

  2. Owner changes EggHuntGame::eggFindThreshold to 100

  3. Owner run EggHuntGame::searchForEgg and win each time

Proof of code

Place following into the EggHuntGameTest.t.sol It is simulation of PoC in which 100 out of 100 cases owner wins.

function testGameOwnerCanMintMaliciously() public {
uint256 ownerTrysFindingEgg = 100;
//this contract is owner so no need to use vm.prank
game.startGame(100);
uint256 existingThreshold = game.eggFindThreshold();
game.setEggFindThreshold(100);
for (uint256 i = 0; i < ownerTrysFindingEgg; i++) {
game.searchForEgg();
}
game.setEggFindThreshold(existingThreshold);
console.log("Owner eggs: ", game.eggsFound(owner));
assertEq(game.eggsFound(owner), ownerTrysFindingEgg);
}

Impact

Since the owner has the ability to win every time they play, the game becomes unfair, and there is no incentive for anyone to compete if the owner participates.

Tools Used

  • VS Code: Cloned the repository locally and identified the vulnerability through manual review.

Recommendations

There can be 2 solutions:

First is that Owner cannot play the game. There must be placed restriction in EggHuntGame::searchForEgg

function searchForEgg() external {
+ require(msg.sender != owner(), "Owner cannot play the game");
require(gameActive, "Game not active");
...

Second solution is that EggHuntGame::eggFindThreshold shouldn't be changed while game is active, only when is incative.

function setEggFindThreshold(uint256 newThreshold) external onlyOwner {
+ require(!gameActive, "Game is active");
require(newThreshold <= 100, "Threshold must be <= 100");
eggFindThreshold = newThreshold;
}
Updates

Lead Judging Commences

m3dython Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Trusted Owner

Owner is trusted and is not expected to interact in ways that would compromise security

Support

FAQs

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