The Path to “Stable Cadence”
Update: Since we made this post a lot has been done, surfacing the latest updates here so you don’t have to scroll all the way down in the comments!
Oct 2022: Another Update on Stable Cadence
Jan 2023: Stable Cadence Preview Release #1
Sep 2023: Update on Cadence 1.0
Dec 2023: Cadence 1.0 Upgrade Plan
One of the most limiting aspects to building on Flow today is the requirement that all smart contracts undergo a security review before deployment on mainnet. Our goal is, and always has been, for mainnet deployment to work like testnet deployment: When you are ready, go for it!
Of course, Cadence is new, and not yet battle-hardened, so to avoid creating a bad experience for users, we have worked with the community to make sure that all smart contracts that are deployed on mainnet stick with the “tried-and-true” features of Cadence that are known to work well. (And to make sure no-one sneaks nasty code on chain in an attempt to exploit possible edge-cases!)
This post is to announce that the core Cadence team is making “Stable Cadence” its highest priority. Stable Cadence is a version of Cadence that is tested and verified to the point where we can recommend that mainnet allows unrestricted smart contract deployment, just like testnet.
There are three main steps involved in getting Stable Cadence released:
- A period of code-hardening, where most or all of the development effort on Cadence is focused on finding and properly handling various edge cases and possible exploits.
- A full, professional code audit of the Cadence code base (audit team to be finalized, but it will be well-established, independent, and the results will be published publicly).
- A period of “incentivized stress testing”, where we use an enhanced bug bounty program to attract as many independent security researchers as possible to further scrutinize the Cadence implementation.
An Opportunity
As we were preparing to turn our focus to Stable Cadence, we realized that there are a small number of improvements to Cadence that are not easy to introduce without breaking existing code. Once Stable Cadence is live and anyone can deploy code anonymously to mainnet, breaking changes will simply not be acceptable. But maybe, just maybe, some breaking changes are acceptable today since we have a relationship with most of the developers that are currently live, and can work with them to update the on-chain code. The pain might be worth it, provided the improvements are significant enough.
Each of the changes listed below has a chance to make future Cadence development significantly more powerful and/or pleasant. Each of them addresses a major stumbling block that developers are seeing today. And each of them requires significant changes to existing code on mainnet; virtually every contract on mainnet would need to be updated if we adopted all of them.
We have written up each of these issues in their own thread, linked below, to encourage discussion and debate. For each issue, if the community overwhelmingly thinks that the improvement is not worth the complexity of updating existing code, we will move forward with the current structure. And, of course, if the community sees the value of any of these changes, we will work with each and every team that is currently live on mainnet to make sure their code works properly under the new implementation.
These discussions should not be seen as a simple up-down vote. We have identified problems and proposed concrete solutions to them, but alternate suggestions are welcome. We just want to create the best language for smart contract development!
The Changes Under Consideration
Here is a list of some of the changes that the team is going to propose to address problems in the current version of Cadence:
-
Streamlined token standards – The current fungible and non-fungible token standards for Flow can only support a single FT or NFT type per contract. It would be beneficial if it was possible to define multiple FT/NFT types per contract. Currently, these standards use type requirements, a language feature which was initially intended to assist with the definition of such standards. However, since the release of Cadence and using these standards, it has become apparent that the standards are limited due to type requirements. Removing type requirements would require changes to the NFT and FT interfaces, which in turn would require code upgrades for all NFT and FT contracts, though the changes would be minimal, and as a result, the standards would be much more flexible and powerful.
-
Improve capabilities – Capabilities are one of the most powerful aspects of Cadence. At the moment we think they are also awkward to learn, frustrating to use, and the code that interacts with them is overly verbose. It would be beneficial to make capabilities much easier for developers to use, by replacing the current API with an alternative, but this would be a fundamental change to the current mechanism for handling capabilities. For example, if the notion of “links” would be removed from Cadence, both code and state updates () would be required.
-
Remove reentrancy “foot-guns” – Cadence makes it very easy to avoid reentrancy attacks: do not allow shared access to global mutable state (i.e. avoid contract variables), ensure your code never has two references to the same instance object live at the same time. Both of these facilities are “bad code smells”, and the kind of thing that an auditor would suggest to strenuously avoid. It would be beneficial to find ways to prevent reentrancy bugs, which would likely require a modification of the language specification.
-
Remove security “foot-guns” – Since the initial release of Cadence, accidental mutability through public fields has been identified as a potential for security issues: Accessing public fields of resources directly can have some surprising side effects. Since resources are overwhelmingly intended to represent assets of value or a mechanism for managing access control, there is a strong argument for preventing developers from accidentally introducing bugs into their contracts.
Potential solutions to this problem have already been proposed in FLIPs 703 and 739, which are open for community feedback.
-
Clarify and fix the behaviour of certain features and functions – For example, references to optionals, storage functions, etc.
Potential improvements have already been proposed in FLIPs 729 and 722, which are open for community feedback.
Other Changes
Stable Cadence will likely include some other minor changes. However, Stable Cadence should not be seen as a feature release, nor should anyone assume we do not care about any key features just because they are not planned as part of Stable Cadence.
Yes, there are many ways that Cadence can (and will!) improve beyond Stable Cadence, and we are as anxious as anyone to see them go live. But the vast majority of these features are purely additive and can be released in future versions without breaking existing code. As such, we do not want to let those features delay the release of Stable Cadence.
Please Weigh In!
If you have any thoughts or questions about the overall idea of “Stable Cadence”, or if you have ideas for key features that should be considered for Stable Cadence since they might break existing code, please comment below.
Please follow the links to the individual proposals above or find all Cadence FLIPs on GitHub, and give feedback. The issues listed above will be explained in much more detail in their own posts, and we are happy to join in the discussion there about the specifics.
––
Much thanks to the whole community for being patient with us as we got to this point! We are all looking forward to hearing your thoughts about how we can make sure Cadence keeps improving.
Thanks also to the Cadence team for helping with this effort and this announcement