2/5
--- ### Precondition Adjustment In our current code review, it's crucial to refine how we manage conditional checks. Instead of employing a broad conditional statement, we're transitioning to using `require`, which serves as a precondition ensuring that the math operations function correctly only if specific conditions are met. This switch from an `if` statement to `require` establishes clearer prerequisites for our test execution. ```solidity require(x == 0 || y == 0 || y <= type(uint256).max / x); ``` ### Debugging with Certora Attempting to run the specification through Certora revealed a compilation error. The error message indicated a missing declaration for `Variable uint256`. The suggested fix involved using `sig` for the function selector. Upon further adjustments, another error surfaced concerning type compatibility. The term `type(uint256).max` is not something that actually exists in Certora’s context so we need to change it as follows: ```solidity max_uint256 ``` But it won't work either :c The reason is because the variable `max_uint256` has a type of `mathint` and not `uint256`, because it cannot underflow nor overflow. so the solution is actually ``` assert_uint256(max_uint256 / x)); ``` This will assert the division is always a `uint256`. ### Learning from Errors The process of encountering and resolving these errors is invaluable. Each error not only points us towards the necessary corrections but also deepens our understanding of the intricacies involved in type handling between different systems like Solidity, CVL, and the tools we use for testing such as Foundry and Certora. ### Final Adjustments and Testing Finally, we adjusted our assertions and retested using `forge test` in Foundry, confirming that our code adjustments were effective even under edge cases identified by Certora.
A detailed guide to refactoring for CVL - This lesson covers how to refactor code for the Certora Verification Language (CVL) including using the `require` keyword, the concept of `max_uint`, and the difference between `mathint` and `uint256` types.
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