
Loading...
Loading
Loading...
LoadingLoading audit report...

WalletGuard.ai, powered by Gestalt Labs
Findings selected for deep verification. Where possible we generated a Solidity proof-of-concept and executed it against a forked mainnet.
src/config/ConfigStorage.solFunction: notifyLines: 225-229src/managers/LandManager.solFunction: _farmPlotsLines: 201-253The analyzed contract is part of a multi-component NFT gaming protocol (Munchables) involving land management, lock mechanisms, migration, rewards, and player account systems. The analysis identified 0 critical, 7 high, 12 medium, 9 low, and 5 informational findings across 39 total deduplicated submissions. The single most dangerous pattern is the pervasive incorrect StorageKey usage in LandManager combined with unbounded schnibble inflation via the NFTOracle role, which together can break all economic logic and allow unlimited in-game currency minting. Overall, the contract system is unsafe for production deployment in its current state; multiple high-severity logic errors would result in direct fund loss, permanent economic imbalance, and broken core gameplay mechanics.
The LandManager contract reads critical game parameters (tax rates, farming rates, plot prices) using the wrong lookup keys. Instead of reading numeric configuration values, it reads contract address slots, which typically return zero or garbage values. This means the farming economy is completely broken: tax rates will be wrong, plot count calculations will fail (likely reverting with a division-by-zero), and farming rewards will be incorrect for all players.
The NFTOracle role can call the reward spray function an unlimited number of times with no cooldown or total cap. Because schnibbles convert into protocol points and ultimately into MunchTokens, a compromised or malicious NFTOracle key could mint an unlimited supply of game currency for any address, completely destroying the token economy.
Every time one player pets another, the schnibble reward is multiplied by 1e18 more than it should be. Since the base value already includes an 1e18 factor for precision, the result is astronomically large (roughly 6.3 followed by 34 zeros). Any player can pet another player once every 10 minutes to instantly accumulate enough schnibbles to max out their NFTs, rendering the entire progression system meaningless.
2 centralization points identified
Loss of the deployer key permanently disables all migration management functions with no recovery path; relevant as a property the buyer should know about.
constructor()Locking outside the lockdrop window is permitted by design but yields no NFTs; users may be confused about receiving no NFTs, and the MigrationManager bypass is documented as intentional. This is a design property to disclose.
_lock()The NFTOracle role can call rewardSpray repeatedly with no cap (Finding 31: removeSpray/rewardSpray unbounded inflation), crediting unlimited schnibbles to any address. Those schnibbles translate to protocol points via ClaimManager. The getRole/onlyRole confusion (Finding 32) may further allow an improperly configured role to bypass intended access controls on spray functions. Combined, a compromised or misconfigured NFTOracle key can inflate schnibbles for colluding players who then convert them to MunchTokens, effectively draining any token reserves allocated for point conversion.
The extra 1e18 multiplication in SnuggeryManager.pet (Finding 16) gives astronomically large schnibble balances per pet action. The unrestricted rewardSpray (Finding 31) can further stack on top of this. A player who both exploits the pet bug and receives spray rewards can achieve maximum NFT chonk/level instantly, then convert points to tokens. The LandManager wrong StorageKey bug (Finding 4) may additionally cause division-by-zero on plot pricing, preventing admin intervention via reconfiguration.
claimYieldForContracts and claimGasFeeForContracts have no access control (Finding 9), allowing any caller to trigger Blast yield claims for arbitrary contract addresses. Combined with reassignBlastGovernor having no access control (Finding 10), an attacker can first deploy a contract that reports RewardsManager as its governor, reassign that contract's governor to themselves, and then call claimYieldForContracts with their contract to redirect yield flows outside the protocol.
| Agent | Status | Findings | Severity | Confidence | Duration | Coverage |
|---|---|---|---|---|---|---|
| reentrancy | success | 8 | 1H3M2L | 79% | 1.5m | Classic reentrancy patterns (external call before state update) in all manager contracts, Cross-function reentrancy in LandManager._farmPlots and LockManager, ERC-777 callback reentrancy via token transfers in LockManager and MigrationManager, CEI pattern compliance in LockManager.lock, unlock, lockOnBehalf, CEI pattern compliance in MigrationManager.lockFundsForAllMigration and migratePurchasedNFTs, nonReentrant modifier placement and coverage in LockManager and MigrationManager, Read-only reentrancy via view functions (getLockedWeightedValue, getTotalChonk), Cross-contract state sharing between AccountManager, LandManager, LockManager, ERC-1155 callback patterns (not applicable - contract uses ERC-721), Flash loan callback patterns in RewardsManager, UUPS upgrade authorization in BaseConfigStorageUpgradeable, Access control on admin functions across all contracts, ConfigStorage notification mechanism and reentrancy through notify(), MigrationManager rescue function correctness, AccountManager spray proposal duplicate detection logic, LandManager configuration key mapping correctness |
| access control | success | 10 | 2H2M | 80% | 1.8m | Access control on all public/external functions across all contracts, Initializer protection in upgradeable contracts (AccountManager, ClaimManager, LandManager, SnuggeryManager), Ownership and role patterns in ConfigStorage (Ownable), BaseConfigStorage (role-based modifiers), UUPS upgrade authorization via _authorizeUpgrade, Signature verification patterns (none found - no ecrecover usage), Delegatecall patterns (none found in custom code - only OZ proxy), Selfdestruct patterns (none found), tx.origin usage (none found for authorization), Reentrancy patterns in LockManager (ReentrancyGuard present), MigrationManager (ReentrancyGuard present), Storage collision in UUPS proxy pattern, Cross-contract authentication via onlyConfiguredContract modifiers, ConfigStorage key overloading/misuse in LandManager and AccountManager, MigrationManager rescue function correctness, RewardsManager yield claim access control, Mock contracts with unprotected state-modifying functions, Arithmetic safety (Solidity 0.8.x checked arithmetic), ERC20 transfer patterns in FundTreasuryDistributor and LockManager |
| economic | success | 14 | 2H4M1L | 77% | 2.8m | Flash loan attack vectors - no token balance dependency for pricing found, Oracle manipulation - no external price feeds (Chainlink, Pyth, etc.) used; prices are set via multi-sig oracle role mechanism, LockManager USD price update mechanism - multi-sig with approve/disapprove thresholds, Governance attacks - no governance token or voting mechanism; role-based access, MEV/sandwich exposure - no DEX swaps in protocol, Reward calculation logic in AccountManager, ClaimManager, SnuggeryManager, Reentrancy - LockManager and MigrationManager use ReentrancyGuard correctly, Access control on all external functions, LandManager configuration loading (found wrong StorageKey usage), AccountManager LandManager address loading via PrimordialsEnabled, MigrationManager payment validation ordering, SnuggeryManager pet schnibble calculation, ClaimManager referral bonus inflation, ConfigStorage notify() gas concerns, UUPS upgrade authorization (onlyAdmin), Integer overflow/underflow (Solidity 0.8.x), Fee-on-transfer token handling in LockManager (SafeERC20 used), Flash loan guards on lock/unlock, Staking reward dilution - not applicable (continuous accrual model), LP token pricing - not applicable, Chainlink/Pyth/Chronicle oracle patterns - not used, L2 sequencer uptime - deployed on Ethereum mainnet (Chain ID 1) |
| logic validation | success | 11 | 1H1M2L | 76% | 1.6m | Input validation and parameter bounds across all contracts, StorageKey usage consistency between ConfigStorage and consuming contracts, LandManager configuration loading with incorrect StorageKeys, AccountManager LandManager integration via PrimordialsEnabled key, FundTreasuryDistributor ETH amount validation in multi-bag scenarios, MigrationManager rescue function ERC20 transfer pattern, MigrationManager access control on migrateAllNFTs, SnuggeryManager pet schnibble calculation units, ClaimManager period points excess calculation, AccountManager spray proposal duplicate detection, LandManager _farmPlots loop bounds and gas consumption, RewardsManager unchecked access to claimYieldForContracts, Integer overflow/underflow in unchecked blocks, Reentrancy patterns in LockManager (protected by ReentrancyGuard), UUPS upgrade authorization, ConfigStorage notification DoS vector, removeSpray underflow protection |
| code quality | success | 14 | 84% | 2.7m | ERC-20 conformance (MunchToken, TestBlastERC20Token, TestERC20Token), ERC-721 conformance (MunchNFT, OldMunchNFT), UUPS upgrade safety (AccountManager, ClaimManager, SnuggeryManager, LandManager), Access control modifiers (onlyConfiguredContract, onlyRole, onlyAdmin, onlyLocalAdmin), Reentrancy guards (LockManager, MigrationManager), Integer overflow/underflow (Solidity 0.8.x checked arithmetic, explicit downcasts), Storage key misuse in LandManager._reconfigure, Cross-contract state consistency in LandManager._farmPlots, Payment validation ordering in MigrationManager.migratePurchasedNFTs, Spray proposal duplicate check mechanism, RewardsManager access control on yield/gas claim functions, ConfigStorage notify() gas griefing potential, Schnibbles precision and scale consistency, getSubAccounts pagination logic, rescue() function ERC20 transferFrom vs transfer, MunchNFT transfer hook ordering, ClaimManager period claim logic | |
| compiler bugs | success | 5 | 1H | 87% | 56.8s | StorageKey aliasing and misconfiguration in LandManager and AccountManager, Access control on all external/public functions, Arithmetic safety in schnibble accounting (removeSpray, feed), Migration flow ordering and ETH validation, Reentrancy in LockManager.lock/unlock (ReentrancyGuard present), UUPS upgrade authorization (_authorizeUpgrade requires onlyAdmin), ConfigStorage notification loop (DoS risk from notify() with many contracts), Schnibble spray proposal duplicate player check logic, Tax rate calculations in LandManager with incorrect constants, Compiler version 0.8.25 - no known critical solc bugs for this version, ABIEncoderV2 - not explicitly enabled, default in 0.8.x, no storage array return pattern matching the 0.4.7-0.5.9 bug, RewardsManager yield/gas claiming access control, MigrationManager ordering of validation vs state changes |
| assembly safety | success | 12 | 1M2L | 82% | 2.1m | Full codepoint scan for non-ASCII characters, RTLO (U+202E), zero-width characters, and homoglyphs in all identifiers and strings, Assembly blocks - only one found in NFTOverlord._toUint256 (benign bytes32->uint256 cast), StorageKey misuse in LandManager._reconfigure() - reading address-typed keys as uint values, Access control on all public/external functions across all contracts, Reentrancy patterns in LockManager, MigrationManager (nonReentrant guards present), Integer overflow/underflow in schnibble arithmetic (Solidity 0.8.x checked math), ERC20 transfer safety (SafeERC20 usage vs raw transfer), UUPS upgrade authorization (onlyAdmin correctly applied), Oracle/price manipulation in LockManager USD price proposal flow, Flash loan attack surface (no flash loans used in protocol), Timestamp dependence in lock/harvest calculations, Checks-effects-interactions in exportMunchable, unlock, lockFundsForAllMigration, ETH value validation in FundTreasuryDistributor and migratePurchasedNFTs, Points emission logic in ClaimManager newPeriod and _claimPoints, ConfigStorage notification DoS potential, Migration data loading and sealing in MigrationManager, Sub-account management in AccountManager, Spray proposal duplicate detection logic |
| l2 specific | success | 15 | 2L | 77% | 2.7m | LandManager configuration and StorageKey usage, AccountManager configuration, schnibble spray logic, and sub-account management, LockManager locking, unlocking, USD price oracle proposal flow, ClaimManager points distribution and period management, SnuggeryManager pet, feed, import/export operations, MigrationManager NFT migration, locking, burning, and rescue function, RewardsManager yield claiming and governor reassignment, BonusManager bonus calculations, NFTOverlord reveal and level-up logic, ConfigStorage notification mechanism and access control, MunchNFT transfer hooks and blacklisting, BaseBlastManager governor configuration, Cross-contract call patterns and CEI violations, Arithmetic overflow/underflow in schnibble calculations, Access control on all external functions, UUPS upgrade authorization, Storage key collision in upgradeable contracts |
| upgrade | success | 14 | 2H2M2L | 79% | 2.9m | UUPS proxy pattern - _authorizeUpgrade access control in BaseConfigStorageUpgradeable, disableInitializers calls in all upgradeable contract constructors, Storage layout across inheritance chain for upgradeable contracts, Initialization risks - initialize() function access and re-entrancy, ConfigStorage role lookup mechanics and getRole vs getUniversalRole distinction, LandManager configuration loading with incorrect StorageKey usage, AccountManager schnibble spray functions and duplicate detection, ClaimManager points accounting and period management, LockManager token locking/unlocking with reentrancy guards, MigrationManager rescue function and migration payment flow, RewardsManager access control on yield claiming functions, RewardsManager governor reassignment without access control, SnuggeryManager chonk calculation and global state tracking, MunchNFT transfer hooks and blacklist enforcement, NFTOverlord reveal queue and RNG request handling, LandManager _farmPlots multi-landlord state update bug, Integer overflow/underflow in schnibble calculations, ERC-1967 implementation slot manipulation, Cross-contract reentrancy through accountManager.updatePlayer callbacks |
This automated audit has inherent limitations. The following areas are not covered.
This report is an automated point-in-time assessment and does not guarantee protection against all possible attacks. It does not cover off-chain components, economic modeling, or business logic correctness unless explicitly noted. Changes to the contract after the audit commit are not reviewed. This is not financial or legal advice. WalletGuard, powered by Gestalt Labs, provides this analysis as-is with no warranty of completeness.
[](https://walletguard.ai/audit/6d48c15f-9a96-4cd4-8417-f6a72e7493e9)
<a href="https://walletguard.ai/audit/6d48c15f-9a96-4cd4-8417-f6a72e7493e9"> <img src="https://walletguard.ai/api/badge/6d48c15f-9a96-4cd4-8417-f6a72e7493e9" alt="WalletGuard Audit Badge" /> </a>