Skip to content
Prev Previous commit
Next Next commit
re-enable using SlotDerivation in Arrays.sol for unsafeAccess
  • Loading branch information
Amxx committed Mar 27, 2024
commit f849734460a75fbcbfc988a7945b75a361602b55
25 changes: 7 additions & 18 deletions contracts/utils/Arrays.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

pragma solidity ^0.8.20;

import {SlotDerivation} from "./SlotDerivation.sol";
import {StorageSlot} from "./StorageSlot.sol";
import {Math} from "./math/Math.sol";

Expand Down Expand Up @@ -379,15 +380,11 @@ library Arrays {
*/
function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
bytes32 slot;
// We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`
// following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays.

/// @solidity memory-safe-assembly
assembly {
mstore(0, arr.slot)
slot := add(keccak256(0, 0x20), pos)
slot := arr.slot
}
return slot.getAddressSlot();
return slot.deriveArray().offset(pos).getAddressSlot();
}

/**
Expand All @@ -397,15 +394,11 @@ library Arrays {
*/
function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
bytes32 slot;
// We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`
// following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays.

/// @solidity memory-safe-assembly
assembly {
mstore(0, arr.slot)
slot := add(keccak256(0, 0x20), pos)
slot := arr.slot
}
return slot.getBytes32Slot();
return slot.deriveArray().offset(pos).getBytes32Slot();
}

/**
Expand All @@ -415,15 +408,11 @@ library Arrays {
*/
function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
bytes32 slot;
// We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`
// following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays.

/// @solidity memory-safe-assembly
assembly {
mstore(0, arr.slot)
slot := add(keccak256(0, 0x20), pos)
slot := arr.slot
}
return slot.getUint256Slot();
return slot.deriveArray().offset(pos).getUint256Slot();
}

/**
Expand Down
17 changes: 7 additions & 10 deletions scripts/generate/templates/Arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { TYPES } = require('./Arrays.opts');
const header = `\
pragma solidity ^0.8.20;

import {SlotDerivation} from "./SlotDerivation.sol";
import {StorageSlot} from "./StorageSlot.sol";
import {Math} from "./math/Math.sol";

Expand Down Expand Up @@ -327,16 +328,12 @@ const unsafeAccessStorage = type => `
function unsafeAccess(${type}[] storage arr, uint256 pos) internal pure returns (StorageSlot.${capitalize(
type,
)}Slot storage) {
bytes32 slot;
// We use assembly to calculate the storage slot of the element at index \`pos\` of the dynamic array \`arr\`
// following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays.

/// @solidity memory-safe-assembly
assembly {
mstore(0, arr.slot)
slot := add(keccak256(0, 0x20), pos)
}
return slot.get${capitalize(type)}Slot();
bytes32 slot;
/// @solidity memory-safe-assembly
assembly {
slot := arr.slot
}
return slot.deriveArray().offset(pos).get${capitalize(type)}Slot();
}`;

const unsafeAccessMemory = type => `
Expand Down