1/5
--- ### Rewriting Tests as Invariants In our discussion, we explore how to transform a test into an invariant, highlighting the practical differences and the strategic considerations between writing a rule and an invariant. We start by renaming our function to `MulWadUpInvariant` to clarify that it's an invariant, maintaining the parameters `uint256 x` and `uint256 y`, consistent with our original setup. ```solidity invariant mulWadUpInvariant(uint256 x, uint256 y) ``` #### Defining the Invariant Our invariant is straightforward: ```solidity mulWadUP(x,y) == assert_uint256(x + y == 0 ? 0 : (x * y - 1) / WAD() + 1); ``` #### Handling Preconditions with Preserved Blocks It's crucial to recognize that the validity of our invariant depends on certain preconditions. In Certora, we manage this through what is known as a preserved block. Here’s how we set it up: ```solidity { preserved { require(x == 0 || y == 0 || y <= type(uint256).max / x); } } ``` Inside the preserved block, we specify the preconditions that need to be true for the invariant to hold reliably. This approach helps in clearly delineating the dependencies of our invariant. #### Running and Testing the Invariant Once the invariant and its preconditions are defined, we proceed to test it alongside our original rule. Both are executed in the context of proving their validity: s We anticipate that both might fail under certain conditions, providing valuable counterexamples that reveal the limitations or errors in our assumptions or logic. ### Analyzing Results Upon testing, we observe failures in both the invariant and the rule, with specific counterexamples pinpointed in the call trace. These examples are crucial for understanding why the failures occur, offering insights into potential issues within the variables or logic used.
A comprehensive guide to using invariants and preserved blocks in Certora. This lesson covers the process of rewriting a rule to be an invariant in Certora, as well as the differences between a rule and an invariant. The lesson also shows how to use preserved blocks in conjunction with invariants to establish conditions necessary for the invariant to hold.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Assembly
Writing smart contracts using Huff and Yul
Ethereum Virtual Machine OPCodes
Formal verification testing
Smart contract invariant testing
Halmos, Certora, Kontrol
Security researcher
$49,999 - $120,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Guest lecturers:
Josselin Feist
Head of Blockchain at Trail of Bits
Last updated on January 17, 2025
Solidity Developer
Assembly and Formal VerificationDuration: 30min
Duration: 4h 38min
Duration: 3h 57min
Duration: 1h 56min
Course Overview
About the course
Assembly
Writing smart contracts using Huff and Yul
Ethereum Virtual Machine OPCodes
Formal verification testing
Smart contract invariant testing
Halmos, Certora, Kontrol
Security researcher
$49,999 - $120,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Guest lecturers:
Josselin Feist
Head of Blockchain at Trail of Bits
Last updated on January 17, 2025
Testimonials
Read what our students have to say about this course.
Chainlink
Chainlink
Gustavo Gonzalez
Solutions Engineer at OpenZeppelin
Francesco Andreoli
Lead Devrel at Metamask
Albert Hu
DeForm Founding Engineer
Radek
Senior Developer Advocate at Ceramic
Boidushya
WalletConnect
Idris
Developer Relations Engineer at Axelar