Summary
Horses can't be fed if block.timestamp % 17 = 0
The issue arises from the code inside FEED_HORSE()
macro which reverts if the condition is met
https://github.com/Cyfrin/2024-01-horse-store/blob/main/src/HorseStore.huff#L86-L89
0x11 timestamp mod
endFeed jumpi
revert
endFeed:
Vulnerability Details
Test Case
To reproduce the test, copy-paste the function inside HorseStoreHuff.t.sol::HorseStoreHuff
then run forge test --mt testHuffCanFeedAnytime
in the terminal.
function testHuffCanFeedAnytime(uint256 time) public {
uint256 horseId = horseStore.totalSupply();
vm.warp(time);
vm.roll(time);
vm.prank(user);
horseStore.mintHorse();
uint256 lastFedTimeStamp = block.timestamp;
horseStore.feedHorse(horseId);
assertEq(horseStore.horseIdToFedTimeStamp(horseId), lastFedTimeStamp);
}
Logs
Running 1 test for test/HorseStoreHuff.t.sol:HorseStoreHuff
[FAIL. Reason: EvmError: Revert; counterexample: calldata=0x6723ffd2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff args=[115792089237316195423570985008687907853269984665640564039457584007913129639935 [1.157e77]]] testHuffCanFeedAnytime(uint256) (runs: 263, μ: 106235, ~: 106235)
Test result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 744.92ms
Ran 1 test suites: 0 tests passed, 1 failed, 0 skipped (1 total tests)
Impact
The protocol will fail to meet its intended functionality, "Horses must be able to be fed at all times."
Tools Used
Foundry fuzz test
Recommendations
#define macro FEED_HORSE() = takes (0) returns (0) {
timestamp // [timestamp]
0x04 calldataload // [horseId, timestamp]
STORE_ELEMENT(0x00) // []
- // End execution
- 0x11 timestamp mod
- endFeed jumpi
- revert
- endFeed:
stop
}