This diagram shows the current flow regarding publishing collections on the blockchain.
createCollection external function called by the creator of a collection
which receives both the address of the
Inside this function, the Forwarder calls another
createCollection function in
the CollectionFactory contract.
This creates a new collection in the blockchain in the form of a MinimalProxy, which delegates all calls made to it to the CollectionImplementation contract containing the logic of how collections should behave.
Without this pattern, every time a collection is created, a new CollectionImplementation contract would have to be deployed. And this contract is BIG, costing a lot of gas in the process.
Thanks to how the EVM handles storage, These proxies can delegate calls to a contract containing the behavior, but updating only their own state.
Let's say a vulnerability is found in the CollectionImplementation contract, or a new magical feature for collections is voted by the community to be added.
With this current implementation, sadly, there is absolutely nothing we can do. The proxies delegate calls to the implementation contract directly, disallowing any kind of modification or upgrade to the collection behavior because they are not upgradable proxies.
This solution implements the Beacon pattern.
Instead of creating minimal proxies delegating calls directly to the implementation, BeaconProxies are created.
These proxies know about an UpgradeableBeacon which is in charge of storing the address of the implementation contract. The proxy asks for this implementation address before delegating the call to that contract.
The owner of the UpgradableBeacon can then update the implementation contract address with another one in order to update the behavior of the proxies, or fix vulnerabilities.
This solution is not retroactive. Collections/Proxies created as MinimalProxies will not obtain upgradable capabilities. Only collections created as BeaconProxies will gain these capabilities.
When updating the implementation contract in the UpgradableBeacon, it is vital that no contract state variables are removed or reordered. Doing so will certainly break things up.
For example, out first implementation has the following variables:
uint256 counter; bool initialized; bytes fingerprint;
The new implementation must have include these variables in the same order even if any of those variables is not used anymore. Any new variable must be defined at the end.
// old variables uint256 counter; bool initialized; bytes fingerprint; // new variables uint256 newCoolCounter; bytes newFingerprint;
More info about this here.
Already being used in Polygon Mainnet.
Main contracts for this solution are:
The first collection created using this pattern in Polygon Mainnet is BEYOND COLLABS at block 28233589