Permalink
Fetching contributors…
Cannot retrieve contributors at this time
124 lines (82 sloc) 8.01 KB

2018-02-28

Bihu Smart Contract Formal Verification

We present a formal verification of the Bihu KEY token operation contracts, upon request from the Bihu team represented by Dr. Bin Lu (Gulu) and Mr. Huafu Bao.

Bihu is a blockchain-based ID system, and KEY is the utility token for the Bihu ID system and community.

The smart contracts requested to be formally verified are the ones for operating the KEY token. The Solidity source code of those contracts and their informal specification are publicly available.

This directory contains the artifact of the Bihu contracts' formal verification, as a companion to the formal verification report:

PDF Bihu Smart Contract Formal Verification

Target Smart Contracts

The target contracts of our formal verification are the following, where we took the Solidity source code from Bihu's Github repository, https://github.com/bihu-id/bihu-contracts, commit f9a7ab65:

More specifically, we formally verified the functional correctness of the following two functions:

Verification Artifacts

Solidity Source Code and Compiled EVM Bytecode

We verified mathematically equivalent variants of each target function. Due to time constraints (we only had two weeks to complete this verification project), we have not verified the external calls to key.balanceOf and key.transfer. We took the modified source code, inlined the DSMath contract and the DSToken contract interface, and compiled it to the EVM bytecode using Remix Solidity IDE (of the version soljson-v0.4.20+commit.3155dd80).

The modified and inlined source code of (the contracts of) each target function:

The EVM (runtime) bytecode generated by the Remix Solidity compiler:

The Remix IDE-generated Gist links:

The (annotated) EVM assemblies disassembled from each bytecode:

The original, inlined source code of (the contracts of) each target function:

Mechanized Specifications and Proofs

Following our formal verification methodology described above, we formalized the high-level specification of the smart contracts based on the informal specification, and the Bihu team has confirmed that the specification correctly captured the intended behavior of their contract. Then, we refined the specification all the way down to the Ethereum Virtual Machine (EVM) level to capture the EVM-specific details. The EVM-level specification is fully mechanized within and automatically verified by our EVM verifier, a correct-by-construction deductive program verifier derived from KEVM and K-framework's reachability logic theorem prover.

The following are the mechanized EVM-level specifications of each target function:

The specifications are written in eDSL, a domain-specific language for EVM specifications, which must be known in order to thoroughly understand our EVM-level specifications. Refer to resources for background on our technology. The above files provide the eDSL specification template parameters. The full K reachability logic specifications are automatically derived by instantiating a specification template with these template parameters.

Run the following command in the root directory of this repository, and it will generate the full specifications under the directory specs/bihu:

$ make bihu

Run the EVM verifier to prove that the specifications are satisfied by (the compiled EVM bytecode of) the target functions. See these instructions for more details of running the verifier.

FAQ

Q: In WarmWallet.modified.inlined.sol, the paused boolean is declared. The bool type is equivalent with the uint8 type, but in the spec file (forwardToHotWallet-spec.ini), the storage location named PAUSED is verified as an uint256. Shouldn't it be

andBool 0 <=Int PAUSED   andBool PAUSED <Int (2 ^Int 8)

instead?

Also, in a failure case, it looks like the storage slot is compared to a shifted value.

andBool PAUSED ==Int 1 <<Int (20 *Int 8)

A: All storage locations have a size of 32 bytes, and multiple items of elementary types that need less than 32 bytes, such as bool or address could be packed into a single storage location only if they fit (Layout of State Variables in Storage). In the contract, the paused boolean is declared right after the owner address, and since they both have a combined size of less than 32 bytes (20 from address and one from bool) they are both kept in the same storage slot, which in the spec file is referenced as PAUSED. Therefore, in order to check that the boolean is true, the storage slot is compared with the value of 1 which is shifted 160 bits (representing the width of the address type) to the left. But this logic is valid only if the address is presumed to be 0.

Resources

Disclaimer