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

Inconsistent Behavior in Huff Implementation of feedHorse Function will leave to unwanted reverts

Summary

The FEED_HORSE macro in the Huff rendition of the HorseStore contract exhibits inconsistent behavior compared to its Solidity counterpart. Specifically, the Huff version includes additional logic that can cause the function to fail based on the current timestamp, a feature not present in the Solidity implementation.

Vulnerability Details

In the Huff code, the FEED_HORSE macro concludes with a sequence of operations that unnecessarily manipulate the timestamp and potentially lead to a revert, depending on the timestamp value. This sequence is:

// End execution
0x11 timestamp mod
endFeed jumpi
revert
endFeed:
stop

This code diverges from the Solidity implementation, where feedHorse(uint256 horseId) unconditionally sets the horseIdToFedTimeStamp[horseId] to block.timestamp without any conditional checks or possible reverts based on the timestamp value.

Impact

This inconsistency can lead to unexpected behavior and errors in the Huff version, reducing the reliability and predictability of the contract. Users might encounter failed transactions in scenarios where the Solidity version would succeed, leading to confusion and potential mistrust in the contract's functionality.

Recommendations

To align the Huff implementation with the Solidity version and ensure consistent behavior, the following modification is recommended:

Remove the extra logic in the FEED_HORSE macro that leads to conditional execution and potential reverts based on the timestamp. The revised macro should simply set the last fed timestamp for the given horse ID, akin to the Solidity implementation. The updated macro should look like this:

```huff
#define macro FEED_HORSE() = takes (0) returns (0) {
    timestamp               // [timestamp]
    0x04 calldataload       // [horseId, timestamp]
    STORE_ELEMENT(0x00)     // []
    stop
}
```

By making these changes, the Huff version of the contract will more accurately reflect the intended behavior as defined in the Solidity implementation, thus maintaining consistency and reliability in the contract's operations.

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 testFeed() public {
address user = makeAddr("user");
deal(user, 1 ether);
vm.warp(10);
vm.roll(10);
vm.startPrank(user);
horseStoreSol.mintHorse();
horseStoreHuff.feedHorse(0);
horseStoreHuff.mintHorse();
horseStoreHuff.feedHorse(0);
vm.warp(17);
horseStoreSol.feedHorse(0);
// @audit this is reverting but it should pass
horseStoreHuff.feedHorse(0);
vm.stopPrank();
}
}
Updates

Lead Judging Commences

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

FEED_HORSE() macro does not allow users to feed a horse if the timestamp is divisible by 17

Support

FAQs

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