Releasing aragonOS 4 – A refinement to our smart contract framework
Enhanced capabilities, reviewed by two independent audits, and depended upon by more than 100 DAOs on the Ethereum Mainnet.
aragonOS 3 was a monumental release which included a lot of potential that is still widely untapped today. Although originally conceived to solely power Aragon organizations, it eventually encapsulated so many strong design decisions that we felt it could be useful to others as a general-purpose smart contract framework. Using its functionality, we were able to take a hard look at every piece of our contract infrastructure and reconsider rebuilding everything on top of the framework (which we did!). The framework went as far as implementing an internal scripting language for permissions, to unlock the vast potential of non-binary permission management. This allows for powerful use cases, like being able to manage an organization's budgeting without ever writing a line of custom code.
If aragonOS 3 was all about pushing the bleeding edge further in smart contract design, aragonOS 4 is the culmination of our efforts to produce a refined, sharpened edge trustworthy for use in the adversarial environment of a public Ethereum network.
Over the last ten months, we put aragonOS 3 through two independent audits and tirelessly gathered feedback from early users of the framework. The code was combed through again and again by ourselves and our auditors, looking for improvements or flaws, and we ultimately ended up touching nearly every line of code–yet again.
We've added enhancements, security guarantees, and more intuitive default behaviours. The contracts have been optimized and tuned to lower their usage costs. And, we've stayed up to date with the latest best practices and developments.
This release, aragonOS 4, now powers more than 140 organizations on mainnet.
Security is paramount
In Q1 and Q2, we kicked off two independent audits on aragonOS 3 in parallel. By the end of Q2, both teams had returned their results and findings, which came to largely inform our design choices for aragonOS 4.
We're happy to announce that both of these teams, the White Hat Group and Consensys Diligence, reviewed our changes for aragonOS 4 and updated their prior reports. To the best of their ability, no exploits could be found by aragonOS 4's release, giving us confidence in deploying the contracts to Mainnet.
However, we would still not recommend committing large amounts of value to be protected by these contracts. Until they have withstood more time in adverse, malicious environments, we cannot declare them mature. No matter how confident we may be about their safety.
To that end, we've launched a bug bounty program on the source code for our deployed smart contract instances.
New features and changes
A highlight of this release is the additional tooling provided to help understand an Aragon application's lifecycle in the EVM. These applications include contracts inheriting from AragonApp, which are typically used behind Proxy contracts to allow users to upgrade their on-chain functionality. You can learn more about this in the Aragon Developer Portal.
Although aragonOS 3 included the ability to initialize application contracts, this was conceived for a technically different reason and did not provide a compelling story for how Aragon developers should deploy and manage their deployed contracts. A more detailed description will be coming in an upcoming blog post about our experience with providing on-chain upgradeability, but the gist of the problem lies in locking down the base contracts that proxies were using for their logic.
The most extreme example of a contract's lifecycle being poorly managed is the unfortunate second incident involving Parity's multisig wallet, where a malicious actor was able to take control of the wallet's base contract, initialize it for their own address, and ultimately destroy it–effectively destroying all proxy instances of the wallet holding real funds.
While nothing as serious as this was ever capable in the contracts we implemented with aragonOS 3 (to the best of our knowledge, no exploits of this kind were possible on Aragon 0.5), it was unnerving and presented unintuitive behaviour that could be easily overlooked by application developers, possibly causing them to write insecure applications.
It was even more unsettling when, as part of their audit, Consensys Diligence was able to initialize our deployed base Kernel contract that was used by Aragon 0.5 organizations on Rinkeby. Again, while this technically could not be exploited, it definitely rang the alarm bells.
aragonOS 4 introduces the concept of petrified contracts. Petrified contracts are ones which can never be initialized, and are frozen in an uninitialized state forever.
By default, base application contracts are immediately petrified upon their deployment, and can only be used by a proxy contract which has been initialized. This makes it clear for users and developers that their contracts follow different lifecycles: the base application contract is never usable or destroyable, and users must deploy and initialize a proxy to use the application.
The second part of this release is about adding more built-in functionality and safety mechanisms to Aragon applications.
We included Forwarding and EVMScript functionality as part of aragonOS 3, and with aragonOS 4, have added built-in fund recoverability and depositable proxies. These four features are now considered together as capabilities, or feature extensions available to applications through AragonApp.
You can learn more about Forwarders and EVMScripts in our aragonOS 3 annoucement post, with the exception that both DelegateScript and DeployDelegateScript were removed due to security concerns.
The new fund-related capabilities allow applications to consciously declare that they should hold funds, or if not, provide a way to recover accidental transfers (receiving ETH can be prevented, but most tokens do not implement a mechanism to detect this). Included with each Kernel is the ability to declare an address to be set as the organization's default vault, which, if an application should not hold funds, will be the recipient of any ETH or tokens sent accidentally to the application.
Another problem we encountered with aragonOS 3 was the inability to use the gas-limited .transfer() and .send() methods for sending ETH to application proxies. A common use case for this would be a fundraising application wanting to securely receive funds from other contracts. Application proxies are now able to declare at runtime whether or not they allow gas-limited transfers, allowing for situations like the aforementioned fundraising contract to accept these transfers only during the period of an ongoing fundraise.
Upgrading our upgrade mechanism
While staying invisible to developers who don't need to maintain old deployments of their aragonOS 3 contracts, this release includes a large architectural change to our upgradeability mechanism: unstructured storage.
An upcoming post will highlight in more detail why we made this change, but in short, it allows us to hide almost all implementation details from a proxy, and therefore, makes it simpler for a user to upgrade to newer versions of aragonOS or even switch to another framework in the future. This design choice was ultimately what which forced us to deprecate old aragonOS 3 organizations (Aragon 0.5 on Rinkeby), but it will be worth it.
We decided to enable the Solidity optimizer in this new release, observing that Solidity's ongoing audit revealed no flaws related to the compiler's optimizer and that many other projects over the summer had chosen to enable it. As almost all deployed contracts, such as the organization templates and app base contracts, are meant to be used many, many times, we optimized aragonOS's contracts for a large number of invocations rather than their deployment cost.
Furthermore, as part of our development efforts, we started tracking bytecode and gas usage differences between changesets. This extra point of data helped to inform us about whether we should favor a particular implementation, or go in another direction. Using these tools, we were also able to discover and validate a number of low-hanging optimizations to slim our gas consumption.
Diffing aragonOS@4.0.1 to aragonOS@3.0.0
As an example of the impact of these optimizations, we were able to take the creation of an organization, including its token, from almost nine million gas in March to just over six today–despite adding more functionality.
Documentation and tooling
We've updated all of our tooling and documentation for aragonOS 4. A migration guide is provided for users of aragonOS 3 who would like to upgrade.
The future–aragonOS 5
We're just wrapping up our new release, but this doesn't mean we're not busy thinking about what lies ahead!
Work on aragonOS 5 has already begun, and we have a number of items on our wishlist, such as:
- Support for meta transactions
- Improvements to the ACL for more complicated permission parameterization
- Enhanced forwarding with more on-chain information
- A global opt-in kill switch in the event of an emergency
We invite you to ask questions, suggest features, or contribute on Github or Aragon Chat!
Subscribe to The Eagle for weekly news on the Aragon Network