StorageSlot.sol 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)
  3. pragma solidity ^0.8.0;
  4. /**
  5. * @dev Library for reading and writing primitive types to specific storage slots.
  6. *
  7. * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
  8. * This library helps with reading and writing to such slots without the need for inline assembly.
  9. *
  10. * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
  11. *
  12. * Example usage to set ERC1967 implementation slot:
  13. * ```
  14. * contract ERC1967 {
  15. * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
  16. *
  17. * function _getImplementation() internal view returns (address) {
  18. * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
  19. * }
  20. *
  21. * function _setImplementation(address newImplementation) internal {
  22. * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
  23. * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
  24. * }
  25. * }
  26. * ```
  27. *
  28. * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
  29. */
  30. library StorageSlot {
  31. struct AddressSlot {
  32. address value;
  33. }
  34. struct BooleanSlot {
  35. bool value;
  36. }
  37. struct Bytes32Slot {
  38. bytes32 value;
  39. }
  40. struct Uint256Slot {
  41. uint256 value;
  42. }
  43. /**
  44. * @dev Returns an `AddressSlot` with member `value` located at `slot`.
  45. */
  46. function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
  47. /// @solidity memory-safe-assembly
  48. assembly {
  49. r.slot := slot
  50. }
  51. }
  52. /**
  53. * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
  54. */
  55. function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
  56. /// @solidity memory-safe-assembly
  57. assembly {
  58. r.slot := slot
  59. }
  60. }
  61. /**
  62. * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
  63. */
  64. function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
  65. /// @solidity memory-safe-assembly
  66. assembly {
  67. r.slot := slot
  68. }
  69. }
  70. /**
  71. * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
  72. */
  73. function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
  74. /// @solidity memory-safe-assembly
  75. assembly {
  76. r.slot := slot
  77. }
  78. }
  79. }