Summary
The FEED_HORSE() Huff macro does not verify if the horseId exists, so any user can feed any horse even if not minted.
Vulnerability Details
You should verify that the horse exists before feeding it.
#define macro FEED_HORSE() = takes (0) returns (0) {
@> timestamp
0x04 calldataload
STORE_ELEMENT(0x00)
Impact
Any new horse may already be fed at its creation, breaking the rule that only horse NFTs can be fed, and that a horse is happy only when it is fed.
Tools Used
Foundry, Manual review
Proof of Concept
This is a test that feeds a horse and mints it afterwards, then expects it to be happy.
function testCanFeedHorseBeforeMint() public {
vm.warp(horseStore.HORSE_HAPPY_IF_FED_WITHIN());
horseStore.feedHorse(0);
vm.warp(block.timestamp + 3600);
vm.prank(user);
horseStore.mintHorse();
bool isHappyHorse = horseStore.isHappyHorse(0);
assertEq(isHappyHorse, true);
}
Run Huff test
forge test --mc HorseStoreHuff --mt testCanFeedNonexistentHorse
Test passes, confirming that the horse was successfuly feeded before mint.
Running 1 test for test/HorseStoreHuff.t.sol:HorseStoreHuff
[PASS] testCanFeedHorseBeforeMint() (gas: 27457)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.52s
Recommended Mitigation
Verify that the horse exists, and throw a custom error if it does not.
#define macro FEED_HORSE() = takes (0) returns (0) {
+ 0x04 calldataload // [tokenId]
+ [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner]
+ // revert if owner is zero address/not minted
+ continue jumpi
+ NOT_MINTED(0x00)
+ continue:
timestamp // [timestamp]