Extend Checkpoints with new sizes and lookup mechanisms (#3589)
This commit is contained in:
@ -3,12 +3,15 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./StorageSlot.sol";
|
||||
import "./math/Math.sol";
|
||||
|
||||
/**
|
||||
* @dev Collection of functions related to array types.
|
||||
*/
|
||||
library Arrays {
|
||||
using StorageSlot for bytes32;
|
||||
|
||||
/**
|
||||
* @dev Searches a sorted `array` and returns the first index that contains
|
||||
* a value greater or equal to `element`. If no such index exists (i.e. all
|
||||
@ -31,7 +34,7 @@ library Arrays {
|
||||
|
||||
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
|
||||
// because Math.average rounds down (it does integer division with truncation).
|
||||
if (array[mid] > element) {
|
||||
if (unsafeAccess(array, mid).value > element) {
|
||||
high = mid;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
@ -39,10 +42,55 @@ library Arrays {
|
||||
}
|
||||
|
||||
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
|
||||
if (low > 0 && array[low - 1] == element) {
|
||||
if (low > 0 && unsafeAccess(array, low - 1).value == element) {
|
||||
return low - 1;
|
||||
} else {
|
||||
return low;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
|
||||
*
|
||||
* WARNING: Only use if you are certain `pos` is lower than the array length.
|
||||
*/
|
||||
function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
|
||||
bytes32 slot;
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
mstore(0, arr.slot)
|
||||
slot := add(keccak256(0, 0x20), pos)
|
||||
}
|
||||
return slot.getAddressSlot();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
|
||||
*
|
||||
* WARNING: Only use if you are certain `pos` is lower than the array length.
|
||||
*/
|
||||
function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
|
||||
bytes32 slot;
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
mstore(0, arr.slot)
|
||||
slot := add(keccak256(0, 0x20), pos)
|
||||
}
|
||||
return slot.getBytes32Slot();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
|
||||
*
|
||||
* WARNING: Only use if you are certain `pos` is lower than the array length.
|
||||
*/
|
||||
function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
|
||||
bytes32 slot;
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
mstore(0, arr.slot)
|
||||
slot := add(keccak256(0, 0x20), pos)
|
||||
}
|
||||
return slot.getUint256Slot();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user