StorageSlotMock.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. const format = require('../format-lines');
  2. const { TYPES } = require('./Slot.opts');
  3. const header = `\
  4. pragma solidity ^0.8.24;
  5. import {Multicall} from "../utils/Multicall.sol";
  6. import {StorageSlot} from "../utils/StorageSlot.sol";
  7. `;
  8. const storageSetValueType = ({ type, name }) => `\
  9. function set${name}Slot(bytes32 slot, ${type} value) public {
  10. slot.get${name}Slot().value = value;
  11. }
  12. `;
  13. const storageGetValueType = ({ type, name }) => `\
  14. function get${name}Slot(bytes32 slot) public view returns (${type}) {
  15. return slot.get${name}Slot().value;
  16. }
  17. `;
  18. const storageSetNonValueType = ({ type, name }) => `\
  19. mapping(uint256 key => ${type}) public ${type}Map;
  20. function set${name}Slot(bytes32 slot, ${type} calldata value) public {
  21. slot.get${name}Slot().value = value;
  22. }
  23. function set${name}Storage(uint256 key, ${type} calldata value) public {
  24. ${type}Map[key].get${name}Slot().value = value;
  25. }
  26. function get${name}Slot(bytes32 slot) public view returns (${type} memory) {
  27. return slot.get${name}Slot().value;
  28. }
  29. function get${name}Storage(uint256 key) public view returns (${type} memory) {
  30. return ${type}Map[key].get${name}Slot().value;
  31. }
  32. `;
  33. const transient = ({ type, name }) => `\
  34. event ${name}Value(bytes32 slot, ${type} value);
  35. function tload${name}(bytes32 slot) public {
  36. emit ${name}Value(slot, slot.as${name}().tload());
  37. }
  38. function tstore(bytes32 slot, ${type} value) public {
  39. slot.as${name}().tstore(value);
  40. }
  41. `;
  42. // GENERATE
  43. module.exports = format(
  44. header,
  45. 'contract StorageSlotMock is Multicall {',
  46. format(
  47. [].concat(
  48. 'using StorageSlot for *;',
  49. '',
  50. TYPES.filter(type => type.isValueType).map(type => storageSetValueType(type)),
  51. TYPES.filter(type => type.isValueType).map(type => storageGetValueType(type)),
  52. TYPES.filter(type => !type.isValueType).map(type => storageSetNonValueType(type)),
  53. TYPES.filter(type => type.isValueType).map(type => transient(type)),
  54. ),
  55. ).trimEnd(),
  56. '}',
  57. );