diff --git a/src/StdStorage.sol b/src/StdStorage.sol index 9d496ca1..7e403758 100644 --- a/src/StdStorage.sol +++ b/src/StdStorage.sol @@ -27,6 +27,7 @@ library stdStorageSafe { Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + uint256 constant MAX_SLOT_READS = 256; function sigs(string memory sigStr) internal pure returns (bytes4) { return bytes4(keccak256(bytes(sigStr))); @@ -123,7 +124,8 @@ library stdStorageSafe { if (reads.length == 0) { revert("stdStorage find(StdStorage): No storage use detected for target."); } else { - for (uint256 i = reads.length; i > 0;) { + uint256 start = reads.length > MAX_SLOT_READS ? reads.length - MAX_SLOT_READS : 0; + for (uint256 i = reads.length; i > start;) { --i; bytes32 prev = vm.load(who, reads[i]); if (prev == bytes32(0)) { diff --git a/test/StdStorage.t.sol b/test/StdStorage.t.sol index ab87da38..39833114 100644 --- a/test/StdStorage.t.sol +++ b/test/StdStorage.t.sol @@ -360,6 +360,15 @@ contract StdStorageTest is Test { vm.expectRevert("stdStorage find(StdStorage): Slot(s) not found."); target.findBalanceOf(address(this)); } + + // Fork regression test for https://github.com/foundry-rs/forge-std/issues/740 + // BabyDoge on BSC is a reflection token whose `balanceOf` reads many slots. + // Before the fix, `deal()` would hang indefinitely. + function test_RevertDealReflectionTokenFork() public { + vm.createSelectFork("https://bsc-rpc.publicnode.com"); + vm.expectRevert("stdStorage find(StdStorage): Slot(s) not found."); + deal(0xc748673057861a797275CD8A068AbB95A902e8de, address(this), 1 ether); + } } contract StorageTestTarget {