Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use immutable variable to store beacon address in BeaconProxy #2538

Closed
Amxx opened this issue Feb 24, 2021 · 2 comments · Fixed by #4435
Closed

Use immutable variable to store beacon address in BeaconProxy #2538

Amxx opened this issue Feb 24, 2021 · 2 comments · Fixed by #4435
Labels
contracts Smart contract code. idea

Comments

@Amxx
Copy link
Collaborator

Amxx commented Feb 24, 2021

🧐 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();
    }
}
@Amxx Amxx added contracts Smart contract code. idea labels Feb 24, 2021
@frangio
Copy link
Contributor

frangio commented Feb 24, 2021

Some people want to have the ability to change the beacon. Imagine that you have a family of contracts sharing the implementation (for easy mass upgrades) but you want to retain the ability to split off one of those contracts to a different beacon.

If we make the beacon immutable, would it be possible to extend the contract to make it a storage variable, overriding a virtual function?

@Amxx
Copy link
Collaborator Author

Amxx commented Feb 25, 2021

My idea was to add an additional ImmutableBeaconProxy in addition to the existing BeaconProxy. Not to replace it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contracts Smart contract code. idea
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants