You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.8 KiB
48 lines
1.8 KiB
const { ethers } = require('hardhat');
|
|
const { setStorageAt } = require('@nomicfoundation/hardhat-network-helpers');
|
|
|
|
const ImplementationLabel = 'eip1967.proxy.implementation';
|
|
const AdminLabel = 'eip1967.proxy.admin';
|
|
const BeaconLabel = 'eip1967.proxy.beacon';
|
|
|
|
const erc1967Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.id(label)) - 1n);
|
|
const erc7201Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.keccak256(erc1967Slot(label))) & ~0xffn);
|
|
const erc7201format = contractName => `openzeppelin.storage.${contractName}`;
|
|
|
|
const getSlot = (address, slot) =>
|
|
ethers.provider.getStorage(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot));
|
|
|
|
const setSlot = (address, slot, value) =>
|
|
Promise.all([
|
|
ethers.isAddressable(address) ? address.getAddress() : Promise.resolve(address),
|
|
ethers.isAddressable(value) ? value.getAddress() : Promise.resolve(value),
|
|
]).then(([address, value]) => setStorageAt(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot), value));
|
|
|
|
const getAddressInSlot = (address, slot) =>
|
|
getSlot(address, slot).then(slotValue => ethers.AbiCoder.defaultAbiCoder().decode(['address'], slotValue)[0]);
|
|
|
|
const upgradeableSlot = (contractName, offset) => {
|
|
try {
|
|
// Try to get the artifact paths, will throw if it doesn't exist
|
|
artifacts._getArtifactPathSync(`${contractName}Upgradeable`);
|
|
return offset + ethers.toBigInt(erc7201Slot(erc7201format(contractName)));
|
|
} catch {
|
|
return offset;
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
ImplementationLabel,
|
|
AdminLabel,
|
|
BeaconLabel,
|
|
ImplementationSlot: erc1967Slot(ImplementationLabel),
|
|
AdminSlot: erc1967Slot(AdminLabel),
|
|
BeaconSlot: erc1967Slot(BeaconLabel),
|
|
erc1967Slot,
|
|
erc7201Slot,
|
|
erc7201format,
|
|
setSlot,
|
|
getSlot,
|
|
getAddressInSlot,
|
|
upgradeableSlot,
|
|
};
|
|
|