Eggstravaganza

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

Owner can change the egg finding chance when a game is active, allowing him to get an advantage over the other users

Description: The function EggHuntGame::setEggFindThreshold can be called at anytime the owner wants to. This brings a huge problem to the protocol. The owner can call the function even when the game is active, meaning he can control when the chance of finding an egg is 100% or close to 0% whilst the game is active. This can become a problem if the owner is trying to use the protocol to his advantage and mint egg NFTs with a higher chance.

function setEggFindThreshold(uint256 newThreshold) external onlyOwner {
require(newThreshold <= 100, "Threshold must be <= 100");
eggFindThreshold = newThreshold;
}

Impact: The owner can find and mint egg NFTs by changing the chance to 100% then changing it back right after he finds an egg to a much lower percentage, getting a huge advantage over the other players.

Proof of Concept:

  1. Owner starts the game

  2. Bob tries to find and egg with a 10% chance

  3. Owner sets the finding chance to 100%

  4. Owner finds and egg and mints the NFT

  5. Owner sets the threshold back to 10

  6. Alice tries to find and egg with a 10% chance

  7. Owner deposits the egg to the Vault

PoC

Put this in EggHuntGameTest.t.sol:

function testOwnerCanChangeThresholdWhenGameIsActiveToHisAdvantage() public {
// owner starts the game and sets the chance low for other users
vm.startPrank(owner);
game.startGame(60);
game.setEggFindThreshold(10);
vm.stopPrank();
// bob tries to find an egg but has a very low chance
vm.prank(bob);
game.searchForEgg();
// owner sets the chance to 100% so he can find an egg
vm.startPrank(owner);
game.setEggFindThreshold(100);
game.searchForEgg();
uint256 tokenId = game.eggCounter();
assertEq(nft.ownerOf(tokenId), owner);
// owner sets the chance back to 10% for other users
game.setEggFindThreshold(10);
vm.stopPrank();
// alice tries to find an egg but has a very low chance
vm.prank(alice);
game.searchForEgg();
// owner stores the NFT to the vault
vm.startPrank(owner);
nft.approve(address(game), tokenId);
game.depositEggToVault(tokenId);
assertTrue(vault.isEggDeposited(tokenId));
vm.warp(block.timestamp + 60);
game.endGame();
}

Recommended Mitigation: To mitigate this it is recommended to add a require at the start of the function to check whether the game is active or not. If it is not active revert the function call.

function setEggFindThreshold(uint256 newThreshold) external onlyOwner {\
+ require(gameActive && block.timestamp <= endTime, "Game is not active");
require(newThreshold <= 100, "Threshold must be <= 100");
eggFindThreshold = newThreshold;
}
Updates

Lead Judging Commences

m3dython Lead Judge 4 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.