Hi, I am researching TransparentUpgradeableProxy and I see it uses immutable variable which is being set to ProxyAdmin address and when upgrading to new implementation this variable is checked to ensure ProxyAdmin initiated request to TransparentUpgradeableProxy for upgrade. That is clear, what is not clear is why TransparentUpgradeableProxy in its constructor is using:
ERC1967Utils.changeAdmin(_proxyAdmin());
why we are setting to some storage slot same ProxyAdmin address. I searched and I cannot find where this storage slot with ProxyAdmin address is being read. Only "useful" variable is immutable variable which is being used is inside TransparentUpgradeableProxy:
address private immutable _admin;
Code to reproduce
contract TransparentUpgradeableProxy is ERC1967Proxy {
// An immutable address for the admin to avoid unnecessary SLOADs before each call
// at the expense of removing the ability to change the admin once it's set.
// This is acceptable if the admin is always a ProxyAdmin instance or similar contract
// with its own ability to transfer the permissions to another account.
address private immutable _admin;
/**
* @dev The proxy caller is the current admin, and can't fallback to the proxy target.
*/
error ProxyDeniedAdminAccess();
/**
* @dev Initializes an upgradeable proxy managed by an instance of a {ProxyAdmin} with an `initialOwner`,
* backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in
* {ERC1967Proxy-constructor}.
*/
constructor(
address _logic,
address initialOwner,
bytes memory _data
) payable ERC1967Proxy(_logic, _data) {
_admin = address(new FijaProxyAdmin(initialOwner));
// Set the storage value and emit an event for ERC-1967 compatibility
ERC1967Utils.changeAdmin(_proxyAdmin());
}
/**
* @dev Returns the admin of this proxy.
*/
function _proxyAdmin() internal virtual returns (address) {
return _admin;
}