ethereum / act

Smart contract specification language
GNU Affero General Public License v3.0
225 stars 37 forks source link

Loop invariants #2

Open leonardoalt opened 5 years ago

leonardoalt commented 5 years ago

@wilcoxjay and I talked today, and he suggested the idea of also expressing loop invariants in the spec.

The challenge there is that loops don't have an interface, so how can we talk about them inside a function in the spec such that they represent loop behavior in different levels, eg, Solidity / bytecode?

One use case is, for example, a tool that runs on the Solidity level inferring loop invariants and trying to communicate these properties to tools that target bytecode.

An idea would be to have the basic spec level of abstraction similar to the ABI, and have extensions to that, such as spec that can also reason about bytecode.

MrChico commented 5 years ago

Here's how we wrote a loop invariant in the act flavor for rpow:

behaviour rpow-loop of Jug
lemma

//  0a3a => 0a7e
pc

    2618 => 2686

for all

    Half   : uint256
    Z      : uint256
    Base   : uint256
    N      : uint256
    X      : uint256

stack

    _ : _ : Half : _ : Z : Base : N : X : WS => Half : _ : #rpow(Z, X, N, Base) : Base : 0 : _ : WS

gas

    194 + ((num0(N) * 172) + (num1(N) * 287))

if

    Half == Base / 2
    0 <= #rpow(Z, X, N, Base)
    #rpow(Z, X, N, Base) * Base < pow256
    N =/= 0
    Base =/= 0
    #sizeWordStack(WS) <= 1000
    num0(N) >= 0
    num1(N) >= 0

which is unsatisfactory on a number of levels.

Now, I think that this syntax is different from what you might like @leonardoalt . Do you have an alternative suggestion?