Sitelet https://github.com/Vectorized/solady/commit/314012eac79efa8246e22db02eaf27a2a59dba87
Skip to content

Commit 314012e

Browse files
authored
🐞 Fix EnumerableSetLib.indexOf for AddressSet (#1552)
1 parent 35d8c9c commit 314012e

3 files changed

Lines changed: 34 additions & 0 deletions

File tree

‎src/utils/EnumerableSetLib.sol‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ library EnumerableSetLib {
772772
bytes32 rootSlot = _rootSlot(set);
773773
/// @solidity memory-safe-assembly
774774
assembly {
775+
value := shr(96, shl(96, value))
775776
if iszero(value) { value := _ZERO_SENTINEL }
776777
result := not(0)
777778
let rootPacked := sload(rootSlot)

‎src/utils/g/EnumerableSetLib.sol‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ library EnumerableSetLib {
780780
bytes32 rootSlot = _rootSlot(set);
781781
/// @solidity memory-safe-assembly
782782
assembly {
783+
value := shr(96, shl(96, value))
783784
if iszero(value) { value := _ZERO_SENTINEL }
784785
result := not(0)
785786
let rootPacked := sload(rootSlot)

‎test/EnumerableSetLib.t.sol‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,4 +904,36 @@ contract EnumerableSetLibTest is SoladyTest {
904904
}
905905
}
906906
}
907+
908+
function testIndexOfDirtyUpperBits() public {
909+
addressSet.add(address(0));
910+
for (uint256 i = 1; i != 5; ++i) {
911+
addressSet.add(address(uint160(i)));
912+
}
913+
assertEq(addressSet.length(), 5);
914+
915+
address dirtyZero = _dirtyAddress(address(0), 1);
916+
assertTrue(addressSet.contains(dirtyZero));
917+
assertEq(addressSet.indexOf(dirtyZero), 0);
918+
919+
address dirtyThree = _dirtyAddress(address(uint160(3)), 0xabc);
920+
assertTrue(addressSet.contains(dirtyThree));
921+
assertEq(addressSet.indexOf(dirtyThree), addressSet.indexOf(address(uint160(3))));
922+
}
923+
924+
function testIndexOfDirtyUpperBitsLazy() public {
925+
addressSet.add(address(0));
926+
addressSet.add(address(uint160(1)));
927+
assertEq(addressSet.length(), 2);
928+
929+
assertEq(addressSet.indexOf(_dirtyAddress(address(0), 1)), 0);
930+
assertEq(addressSet.indexOf(_dirtyAddress(address(uint160(1)), 0xabc)), 1);
931+
}
932+
933+
function _dirtyAddress(address a, uint256 dirt) internal pure returns (address result) {
934+
/// @solidity memory-safe-assembly
935+
assembly {
936+
result := or(a, shl(160, dirt))
937+
}
938+
}
907939
}

0 commit comments

Comments
 (0)