Skip to main content

25 posts tagged with "Coq"

View All Tags

Β· 3 min read

In this blog post, we present our project to formally verify the implementation of the type checker for smart contracts of the πŸ’§Β Sui blockchain. The Sui blockchain uses the Move language to express smart contracts. This language is implemented in πŸ¦€Β Rust and compiles down to the Move bytecode that is loaded in memory when executing the smart contracts.

We will formally verify the part that checks that the bytecode is well-typed, so that when a smart contract is executed it cannot encounter critical errors. The type checker itself is also written in Rust, and we will verify it using the proof assistant CoqΒ πŸ“ and our tool coq-of-rust that translates Rust programs to Coq.

Β· 7 min read

In this blog post we explain how we specify and formally verify a whole ERC-20 smart contract using our tool coq-of-solidity, which translates Solidity code to the proof assistant CoqΒ πŸ“.

The proofs are still tedious for now, as there are around 1,000 lines of proofs for 100 lines of Solidity. We plan to automate this work as much as possible in the subsequent iterations of the tool. One good thing about the interactive theorem prover Coq is that we know we can never be stuck, so we can always make progress in our proof techniques and verify complex properties even if it takes time ✨.

Formal verification with an interactive proof assistant is the strongest way to verify programs since:

  • it covers all possible inputs and program states,
  • it checks any kind of properties.

Β· 11 min read

We continue to strengthen the security of smart contracts with our tool coq-of-solidity πŸ› οΈ. It checks for vulnerabilities or bugs in Solidity code. It uses formal verification with an interactive theorem prover (CoqΒ πŸ“) to make sure that we cover:

  • all possible user inputs/storage states, even if there are infinite possibilities,
  • for any security properties.

This is very important as a single bug can lead to the loss of millions of dollars in smart contracts, as we have regularly seen in the past, and we can never be sure that a human review of the code did not miss anything.

Our tool coq-of-solidity is one of the only tools using an interactive theorem prover for Solidity, together with Clear from Nethermind. This might be the most powerful approach to making code without bugs, as exemplified in this PLDI paper comparing the reliability of various C compilers. They found numerous bugs in each compiler except in the formally verified one!

In this blog post we show how we functionally specify and verify the _approve function of an ERC-20 smart contract. We will see how we prove that a refined version of the function is equivalent to the original one.

Β· 7 min read

We continue to work on our open source formal verification tool for Solidity named coq-of-solidity πŸ› οΈ. Formal verification is the strongest form of code audits, as we verify that the code behaves correctly in all possible execution cases πŸ”. We use the interactive theorem prover Coq to express and verify any kinds of properties.

We work by translating the Yul version of a smart contract to the formal language CoqΒ πŸ“, in which we then express the code specifications/security properties and formally verify them πŸ”„. The Yul language is an intermediate language used by the Solidity compiler and others to generate EVM bytecode. Yul is simpler than Solidity and at a higher level than the EVM bytecode, making it a good target for formal verification.

In this blog post we present the recent developments we made to simplify the reasoning 🧠 about Yul programs once translated in Coq.

Β· 17 min read

Solidity is the most widely used smart contract language on the blockchain. As smart contracts are critical software handling a lot of money, there is a huge interest in finding all possible bugs before putting them into production.

Formal verification is a technique to test a program on all possible entries, even when there are infinitely many. This contrasts with the traditional test techniques, which can only execute a finite set of scenarios. As such, it appears to be an ideal way to bring more security to smart contract audits.

In this blog post, we present the formal verification tool coq-of-solidity that we are developing for Solidity. Its specificities are that:

  1. It is open-source (GPL-3 for the translation, MIT for the proofs).
  2. It uses an interactive theorem prover, the system Coq, to verify arbitrarily complex properties.

Here, we present how we translate Solidity code into Coq using the intermediate language Yul. We explain the semantics we use and what remains to be done.

The code is available in our fork of the Solidity compiler at github.com/formal-land/coq-of-solidity.

Β· 9 min read

In order to formally verify Python code in Coq our approach is the following:

  1. Import Python code in Coq by running coq-of-python.
  2. Write a purely functional simulation in Coq of the code.
  3. Show that this simulation is equivalent to the translation.
  4. Verify the simulation.

We will show in this article how we can merge the steps 2. and 3. to save time in the verification process. We do so by relying on the proof mode of Coq and unification.

Our mid-term goal is to formally specify the Ethereum Virtual Machine (EVM) and prove that this specification is correct according to reference implementation of the EVM in Python. This would ensure that it is always up-to-date and exhaustive. The code of this project is open-source and available on GitHub: formal-land/coq-of-python.

Β· 7 min read

We are continuing to specify the Ethereum Virtual Machine (EVM) in the formal verification languageΒ Coq. We are working from the automatic translation in Coq of the reference implementation of the EVM, which is written in the language Python.

In this article, we will see how we specify the EVM in Coq by writing an interpreter that closely mimics the behavior of the Python code. We call that implementation a simulation as it aims to reproduce the behavior of the Python code, the reference.

In contrast to the automatic translation from Python, the simulation is a manual translation written in idiomatic Coq. We expect it to be ten times smaller in lines compared to the automatic translation, and of about the same size as the Python code. This is because the automatic translation needs to encode all the Python specific features in Coq, like variable mutations and the class system.

In the following article, we will show how we can prove that the simulation is correct, meaning that it behaves exactly as the automatic translation.

The code of this project is open-source and available on GitHub: formal-land/coq-of-python. This work follows a call from Vitalik Buterin for more formal verification of the Ethereum's code.

Β· 11 min read

We are starting to work on a new product, coq-of-python. The idea of this tool is, as you can guess, to translate Python code to the proof system Coq.

We want to import specifications written in Python to a formal system like Coq. In particular, we are interested in the reference specification of Ethereum, which describes how EVM smart contracts run. Then, we will be able to use this specification to either formally verify the various implementations of the EVM or smart contracts.

All this effort follows a Tweet from Vitalik Buterin hoping for more formal verification of the Ethereum's code:

One application of AI that I am excited about is AI-assisted formal verification of code and bug finding.

Right now ethereum's biggest technical risk probably is bugs in code, and anything that could significantly change the game on that would be amazing.

β€” Vitalik Buterin

We will now describe the technical development of coq-of-python. For the curious, all the code is on GitHub: formal-land/coq-of-python.

Β· 6 min read

We continue our work on formal verification of Rust programs with our tool coq-of-rust, to translate Rust code to the formal proof system Coq. One of the limitation we had was the handling of primitive constructs from the standard library of Rust, like Option::unwrap_or_default or all other primitive functions. For each of these functions, we had to make a Coq definition to represent its behavior. This is both tedious and error prone.

To solve this issue, we worked on the translation of the core and alloc crates of Rust using coq-of-rust. These are very large code bases, with a lot of unsafe or advanced Rust code. We present what we did to have a "best effort" translation of these crates. The resulting translation is in the following folders:

Β· 6 min read

At Formal Land our mission is to reduce the cost of finding bugs in software. We use formal verification, that is to say mathematical reasoning on code, to make sure we find more bugs than with testing. As part of this effort, we are working on a tool coq-of-rust to translate Rust code to Coq, a proof assistant, to analyze Rust programs. Here we present a technical improvement we made in this tool.

One of the challenges of our translation from Rust to Coq is that the generated code is very verbose. The size increase is about ten folds in our examples. A reasons is that we use a monad to represent side effects in Coq, so we need to name each intermediate result and apply the bind operator. Here, we will present a monadic notation that prevents naming intermediate results to make the code more readable.