Skip to content

Commit fac7bd8

Browse files
authored
fix(stdStorage): wrong slot id may returned by find() when slot value == 1337 (#446)
* fix(stdStorage): wrong slot id may returned by `find()` when slot value == 1337 * chore: type cast optimization * use snake case to match the naming styles
1 parent d7f4713 commit fac7bd8

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

src/StdStorage.sol

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,20 @@ library stdStorageSafe {
6868
if (prev == bytes32(0)) {
6969
emit WARNING_UninitedSlot(who, uint256(reads[i]));
7070
}
71+
if (prev != fdat) {
72+
continue;
73+
}
74+
bytes32 new_val = ~prev;
7175
// store
72-
vm.store(who, reads[i], bytes32(hex"1337"));
76+
vm.store(who, reads[i], new_val);
7377
bool success;
74-
bytes memory rdat;
7578
{
79+
bytes memory rdat;
7680
(success, rdat) = who.staticcall(cald);
7781
fdat = bytesToBytes32(rdat, 32 * field_depth);
7882
}
7983

80-
if (success && fdat == bytes32(hex"1337")) {
84+
if (success && fdat == new_val) {
8185
// we found which of the slots is the actual one
8286
emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));
8387
self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);

test/StdStorage.t.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ contract StdStorageTest is Test {
2121
assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find());
2222
}
2323

24+
function test_StorageExtraSload() public {
25+
assertEq(16, stdstore.target(address(test)).sig(test.extra_sload.selector).find());
26+
}
27+
2428
function test_StorageCheckedWriteHidden() public {
2529
stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100);
2630
assertEq(uint256(test.hidden()), 100);
@@ -271,6 +275,7 @@ contract StorageTest {
271275
address public tF = address(1337);
272276
int256 public tG = type(int256).min;
273277
bool public tH = true;
278+
bytes32 private tI = ~bytes32(hex"1337");
274279

275280
constructor() {
276281
basic = UnpackedStruct({a: 1337, b: 1337});
@@ -299,4 +304,12 @@ contract StorageTest {
299304
function const() public pure returns (bytes32 t) {
300305
t = bytes32(hex"1337");
301306
}
307+
308+
function extra_sload() public view returns (bytes32 t) {
309+
// trigger read on slot `tE`, and make a staticcall to make sure compiler doesn't optimize this SLOAD away
310+
assembly {
311+
pop(staticcall(gas(), sload(tE.slot), 0, 0, 0, 0))
312+
}
313+
t = tI;
314+
}
302315
}

0 commit comments

Comments
 (0)