erc1967.js 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. const { ethers } = require('hardhat');
  2. const { getStorageAt, setStorageAt } = require('@nomicfoundation/hardhat-network-helpers');
  3. const ImplementationLabel = 'eip1967.proxy.implementation';
  4. const AdminLabel = 'eip1967.proxy.admin';
  5. const BeaconLabel = 'eip1967.proxy.beacon';
  6. function labelToSlot(label) {
  7. return ethers.toBeHex(BigInt(ethers.keccak256(ethers.toUtf8Bytes(label))) - 1n);
  8. }
  9. function getSlot(address, slot) {
  10. return getStorageAt(
  11. ethers.isAddress(address) ? address : address.address,
  12. ethers.isBytesLike(slot) ? slot : labelToSlot(slot),
  13. );
  14. }
  15. function setSlot(address, slot, value) {
  16. return setStorageAt(
  17. ethers.isAddress(address) ? address : address.address,
  18. ethers.isBytesLike(slot) ? slot : labelToSlot(slot),
  19. value,
  20. );
  21. }
  22. async function getAddressInSlot(address, slot) {
  23. const slotValue = await getSlot(address, slot);
  24. return ethers.getAddress(slotValue.substring(slotValue.length - 40));
  25. }
  26. module.exports = {
  27. ImplementationLabel,
  28. AdminLabel,
  29. BeaconLabel,
  30. ImplementationSlot: labelToSlot(ImplementationLabel),
  31. AdminSlot: labelToSlot(AdminLabel),
  32. BeaconSlot: labelToSlot(BeaconLabel),
  33. setSlot,
  34. getSlot,
  35. getAddressInSlot,
  36. };