Summary
If even 1 second has passed since a horse was fed, then the 'HorseStore.huff::IS_HAPPY_HORSE' function will determine that the horse is not happy. This is incorrect as it should be happy if it has been fed within 24 hours.
Vulnerability Details
In the 'HorseStore.huff::IS_HAPPY_HORSE' function, it incorrectly calculates the timestamp values with the [HORSE_HAPPY_IF_FED_WITHIN_CONST] constant using a lt (Less Than) operation. This means that if any time has passed since the horse was fed, it will determine that the horse is not happy.
Impact
The below test fails showing that if even 1 second has passed, then the horse will be unhappy
function testHuffIS_HAPPY_HORSEWillFailIfAnyTimeHasPassed() public {
uint256 horseId = horseStore.totalSupply();
vm.warp(100000);
vm.roll(86400);
vm.prank(user);
horseStore.mintHorse();
horseStore.feedHorse(horseId);
assertEq(horseStore.isHappyHorse(horseId), true);
vm.warp(100001);
vm.roll(86401);
assertEq(horseStore.isHappyHorse(horseId), true);
}
Tools Used
--Foundry
Recommendations
It is recommended to change the lt (Less Than) operation with a gt (Greater Than) operation so that it will calculate the horses happiness correctly.
#define macro IS_HAPPY_HORSE() = takes (0) returns (0) {
0x04 calldataload // [horseId]
LOAD_ELEMENT(0x00) // [horseFedTimestamp]
timestamp // [timestamp, horseFedTimestamp]
dup2 dup2 // [timestamp, timestamp, timestamp, horseFedTimestamp]
sub // [timestamp - horseFedTimestamp, timestamp, horseFedTimestamp]
[HORSE_HAPPY_IF_FED_WITHIN_CONST] // [HORSE_HAPPY_IF_FED_WITHIN, timestamp - horseFedTimestamp, timestamp, horseFedTimestamp]
- lt // [HORSE_HAPPY_IF_FED_WITHIN < timestamp - horseFedTimestamp, timestamp, horseFedTimestamp]
+ gt // [HORSE_HAPPY_IF_FED_WITHIN < timestamp - horseFedTimestamp, timestamp, horseFedTimestamp]
start_return_true jumpi // [timestamp, horseFedTimestamp]
eq // [timestamp == horseFedTimestamp]
start_return
jump
start_return_true:
0x01
start_return:
// Store value in memory.
0x00 mstore
// Return value
0x20 0x00 return
}