Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: low
Valid

Feeding Unminted Horse

Summary

There is a logical issue in the feedHorse(uint256 horseId) function, where it currently allows feeding of horses that may not have been minted yet. This oversight could lead to inconsistencies and unexpected behavior within the contract's state.

Vulnerability Details

The feedHorse function updates the horseIdToFedTimeStamp mapping to record the last time a horse was fed. However, this function does not verify whether the horseId provided corresponds to a horse that has been minted and exists within the contract. As a result, it is possible to feed a horse that doesn't exist (i.e., a horse with an ID that has not been minted yet).

Impact

This logical flaw could lead to several issues:

  1. It allows users to interact with non-existent NFTs, leading to a state where the contract records and acts upon invalid data.

  2. It may cause confusion and potentially impact the integrity of the game mechanics, especially if the state of unminted horses is queried or utilized in other functions or external contracts.

Tools Used

Manual revision

Recommendations

To address this issue, implement a check in the feedHorse function to ensure that the horse has been minted before allowing it to be fed. This can be achieved by comparing the horseId against the totalSupply() of the contract, as totalSupply() indicates the number of horses minted so far. Here is a suggested modification:

function feedHorse(uint256 horseId) external {
require(horseId < totalSupply(), "HorseStore: Cannot feed an unminted horse");
horseIdToFedTimeStamp[horseId] = block.timestamp;
}

This change ensures that the feedHorse function will only execute if the horseId is valid (i.e., the horse has been minted). It uses totalSupply() as a reference since the mintHorse function mints horses sequentially starting from 0. This check will prevent users from interacting with non-existent horses and help maintain the integrity and intended functionality of the contract.

POC

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {Test, console2} from "forge-std/Test.sol";
import {HuffDeployer} from "foundry-huff/HuffDeployer.sol";
import {HorseStore} from "../src/HorseStore.sol";
import {IERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
contract MixedHuffTest is Test {
string public constant NFT_NAME = "HorseStore";
string public constant NFT_SYMBOL = "HS";
string public constant horseStoreLocation = "HorseStore";
HorseStore horseStoreHuff;
HorseStore horseStoreSol;
function setUp() public {
horseStoreSol = new HorseStore();
horseStoreHuff = HorseStore(
HuffDeployer.config().with_args(bytes.concat(abi.encode(NFT_NAME), abi.encode(NFT_SYMBOL))).deploy(
horseStoreLocation
)
);
}
function tesFeed() public {
address user = makeAddr("user");
deal(user, 1 ether);
vm.warp(10);
vm.roll(10);
vm.startPrank(user);
horseStoreSol.mintHorse();
horseStoreSol.feedHorse(0);
// @audit this should fail, but it doesn't
horseStoreSol.feedHorse(110);
horseStoreHuff.mintHorse();
horseStoreHuff.feedHorse(0);
// @audit this should fail, but it doesn't
horseStoreHuff.feedHorse(110);
vm.stopPrank();
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Nonexistent horses can be fed

Support

FAQs

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