SlotDerivation.t.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. const format = require('../format-lines');
  2. const { capitalize } = require('../../helpers');
  3. const { TYPES } = require('./Slot.opts');
  4. const header = `\
  5. pragma solidity ^0.8.20;
  6. import {Test} from "forge-std/Test.sol";
  7. import {SlotDerivation} from "@openzeppelin/contracts/utils/SlotDerivation.sol";
  8. `;
  9. const array = `\
  10. bytes[] private _array;
  11. function testDeriveArray(uint256 length, uint256 offset) public {
  12. length = bound(length, 1, type(uint256).max);
  13. offset = bound(offset, 0, length - 1);
  14. bytes32 baseSlot;
  15. assembly {
  16. baseSlot := _array.slot
  17. sstore(baseSlot, length) // store length so solidity access does not revert
  18. }
  19. bytes storage derived = _array[offset];
  20. bytes32 derivedSlot;
  21. assembly {
  22. derivedSlot := derived.slot
  23. }
  24. assertEq(baseSlot.deriveArray().offset(offset), derivedSlot);
  25. }
  26. `;
  27. const mapping = ({ type, name, isValueType }) => `\
  28. mapping(${type} => bytes) private _${type}Mapping;
  29. function testDeriveMapping${name}(${type} ${isValueType ? '' : 'memory'} key) public {
  30. bytes32 baseSlot;
  31. assembly {
  32. baseSlot := _${type}Mapping.slot
  33. }
  34. bytes storage derived = _${type}Mapping[key];
  35. bytes32 derivedSlot;
  36. assembly {
  37. derivedSlot := derived.slot
  38. }
  39. assertEq(baseSlot.deriveMapping(key), derivedSlot);
  40. }
  41. `;
  42. // GENERATE
  43. module.exports = format(
  44. header.trimEnd(),
  45. 'contract SlotDerivationTest is Test {',
  46. 'using SlotDerivation for bytes32;',
  47. '',
  48. array,
  49. TYPES.flatMap(type =>
  50. [].concat(
  51. type,
  52. (type.variants ?? []).map(variant => ({
  53. type: variant,
  54. name: capitalize(variant),
  55. isValueType: type.isValueType,
  56. })),
  57. ),
  58. ).map(type => mapping(type)),
  59. '}',
  60. );