Summary:
All three contracts use string error messages in require()
statements instead of more gas-efficient custom errors, resulting in higher deployment and runtime costs.
Vulnerability Details:
EggHuntGame.sol
require(_eggNFTAddress != address(0), "Invalid NFT address");
require(_eggVaultAddress != address(0), "Invalid vault address");
require(!gameActive, "Game already active");
require(duration >= MIN_GAME_DURATION, "Duration too short");
require(gameActive, "Game not active");
require(newThreshold <= 100, "Threshold must be <= 100");
require(block.timestamp >= startTime, "Game not started yet");
require(block.timestamp <= endTime, "Game ended");
require(eggNFT.ownerOf(tokenId) == msg.sender, "Not owner of this egg");
EggVault.sol
require(_eggNFTAddress != address(0), "Invalid NFT address");
require(eggNFT.ownerOf(tokenId) == address(this), "NFT not transferred to vault");
require(!storedEggs[tokenId], "Egg already deposited");
require(storedEggs[tokenId], "Egg not in vault");
require(eggDepositors[tokenId] == msg.sender, "Not the original depositor");
EggstravaganzaNFT.sol
require(_gameContract != address(0), "Invalid game contract address");
require(msg.sender == gameContract, "Unauthorized minter");
Impact
Tools Used
Manual review
Recommendations
Define Custom Errors at Contract Level:
error InvalidAddress();
error GameAlreadyActive();
error GameNotActive();
error InvalidDuration();
error InvalidThreshold();
error GameNotStarted();
error GameEnded();
error NotEggOwner();
error NFTNotTransferred();
error EggAlreadyDeposited();
error EggNotInVault();
error NotDepositor();
error UnauthorizedMinter();
Replace All Require Statements:
require(_eggNFTAddress != address(0), "Invalid NFT address");
if (_eggNFTAddress == address(0)) revert InvalidAddress();