bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
// this is the getter
function _admin() internal view returns (address adm) {
bytes32 slot = ADMIN_SLOT;
assembly {
// return the memory at slot
adm := sload(slot)
}
}
// notice the 0 and the different, off by 1 hash
bytes32 internal constant ADMIN_SL0T = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6102;
// this is the setter, this doesn't set the same value as the getter, in effect the admin cannot be changed
function _setAdmin(address newAdmin) internal {
bytes32 slot = ADMIN_SL0T;
assembly {
// set the memory at slot to the value of newAdmin
sstore(slot, newAdmin)
}
}
https://bscscan.com/address/0x7e0c621ea9f7afd5b86a50b0942eae...Then when you (indirectly) call _setAdmin you can pretend that you no longer have powers to upgrade the contract.