As a major development center within the Tezos ecosystem, Nomadic Labs routinely performs ongoing reviews and analysis of the Tezos protocol code. In conducting a recent review of the Granada proposal, we identified a low-severity bug that occurs in an uncommon pattern in the handling of comparisons, which we would like to raise awareness of so that developers and bakers can be best informed.
The bug was introduced when refactoring the Michelson interpreter. The refactoring dramatically improves gas consumption (typically by 5x or more), but a case was missed out in the Michelson
COMPARE function (for Michelson values): when comparing two pairs where the first element of each pair is an option type set to
COMPARE concludes that the two values are equal when correct behaviour would be to recursively compare the right parts of the pairs. For example:
Pair None 3 and
Pair None 5 would be deemed equal by the Granada
COMPARE operator, when they should not be because
5 are not equal. The ability to compare option types in Michelson is fairly new and was introduced in Edo. This was further confirmed after we reviewed the contracts deployed on Mainnet, Florencenet, and Granadanet and found that no contracts currently use the pattern that would trigger this bug. Thus, no current contracts would be affected by this error in the Granada proposal.
Please note that future contracts could be affected in the following two scenarios:
- comparing values that include option types, or
- using values that include option types as keys in sets or maps (big maps are unaffected).
Neither use case is common, and even if they do appear, they only affect the contract using it, not the protocol as a whole.
While the Michelson interpreter is well covered by tests and pair and option types are tested, the uncommon combination that triggers this bug was not, so this bug was missed by the test suite.
To better detect such errors in future, we updated our test suite to use property-based testing. Property-based testing is an approach that automatically generates random test cases that try to break a function’s desired properties, and is better able to help surface these types of bugs caused by uncommon pattern use. We used property-based testing recently to test properties of the smart contracts used in Liquidity Baking.
If Granada is adopted in the next voting period then:
- A fix for the comparison bug will be included in the subsequent “H”-named protocol. If adopted we would expect this to activate in October 2021.
- Although developers are unlikely to use the patterns that produce incorrect behavior as described above, for safety and convenience purposes we will provide a linting tool to help detect them in code.