Closed
Description
🧐 Motivation
Unlike the transparent proxy, the _BEACON_SLOT
that is part of the BeaconProxy design doesn't need to be updated to update the proxy. Its rather the opposite:
- Upgrades are to be performed in the beacon's storage space
- Changed to the
_BEACON_SLOT
could, if performed incorrectly by the implementation, break the proxy.
In some cases the ability to update the _BEACON_SLOT
might be a welcomed feature... but in other cases, it might be a cost (an sload is required) and an eventual security issue.
📝 Details
For cases where upgradeability of the _BEACON_SLOT
is not requiered, the beacon address could be stored using an immutable variable. This would provide a new ImmutableBeaconProxy
implementation
contract ImmutableBeaconProxy is Proxy {
IBeacon immutable private _beacon;
constructor(address beacon, bytes memory data) payable {
require(
Address.isContract(beacon),
"BeaconProxy: beacon is not a contract"
);
require(
Address.isContract(IBeacon(beacon).implementation()),
"BeaconProxy: beacon implementation is not a contract"
);
_beacon = IBeacon(beacon);
if (data.length > 0) {
// cannot call `_implementation()` because immutable variables cannot be read during construction.
Address.functionDelegateCall(IBeacon(beacon).implementation(), data, "BeaconProxy: function call failed");
}
}
function _implementation() internal view override returns (address) {
return _beacon.implementation();
}
}