Smart contract packages — upgradeability for normal people

TJ VanSlooten
3 min readJul 27, 2022

--

How did we get here?

In December 2021, I was introduced to an EIP that deeply excited me. Being fresh off a smart contract development bootcamp, I decided to dive right into EIP2535 and learn everything I could about Nick Mudge’s “Diamond” framework. In short, this modular way of building smart contracts means that any deployed contract can be shared and added to any other diamond contract system. In addition, a diamond contract’s functionality can be near infinite. To learn about diamonds, start here.

At the base of every economy there is a contract. At 0xHabitat, we decided we’d like to leverage EIP2535 to build decision-making (governance) modules for economies to re-use on-chain. The reusability of “facets” (diamond implementation contracts) gives contract owners maximum long-term flexibility and defers the ceiling of immutability in designing contract systems.

While working on different governance approaches for managing EIP2535 contract systems, we theorized that presets would be beneficial for easy integration with our multi-facet decision-making system. Thus, the idea for smart contract packages was born.

What is a package?

A package is a pre-configured diamondCut living on-chain that can be used to upgrade a diamond in one transaction. There can be many approaches to this, and ours continues to evolve at Habitat. In my initial design, I chose to use a MinimalProxyFactory to cheaply deploy new minimal proxies of an implementation that stores a diamondCut:

function diamondCut(facetCuts[{address,action,selectors}, .. ], initAddr, initFunc)

Though it has changed slightly, the original design allowed a package to be used as a proposalContract in Nick Mudge’s governance-token-diamond implementation, which I rewrote with solidity ^0.8.0 using solidstate. The design of these packages is still evolving and may even reverse course in some ways. You can find the source code here.

What is 0xpm?

0xpm.app is an upgradeable contract system that provides easier upgradeability to other diamonds by allowing them to install, uninstall, and/or update “packages”. It achieves this by storing the minimal proxy addresses of the diamondCut args, though other approaches are under experimentation. You can watch a demo of the prototype here.

What’s so special?

The development team at 0xHabitat has come up with some clever ways to use contract metadata from ipfs. The hardhat-gemcutter plug-in makes working with diamonds simple and handles automatic metadata publishing to ipfs. We are now using this metadata fetching technique with typechain in our development environment for the 0xHabitat governance modules, which has brought useDapp to adopt the same technique. The 0xpm prototype has only dipped its toes into the potential of this technique. 0xpm handles ipfs metadata fetching, but does not yet allow for publishing metadata, though it may be in the pipeline as research continues.

Which problems are ahead?

While the 0xpm contracts continue to evolve, a few of the immediate issues we face are:

  • handling upgrade initializers in installing, uninstalling, and updating a package.
  • Rewarding package library contributors via tokenomic design.
  • Combining approaches for sharing front-end and contract code together (see: bit.dev, single-spa, storybook)
  • Creating a CLI for integration into local development environments.

While we have reasoned some solutions to these problems, we invite anyone to participate in solving these and other problems with us at as we strive for web3 economies that are composable, governable, and adaptable. If you’d like to get involved with this project, please leave a comment or message me on Twitter for now.

--

--