Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- requires "domains.k"
- requires "edsl.k"
- requires "evm.k"
- module RULES
- imports EVM
- imports EDSL
- // VERIFICATION.k
- syntax Int ::= nthbyteof ( Int , Int , Int ) [function, smtlib(smt_nthbyteof), proj]
- // ------------------------------------------------------------------------------
- rule nthbyteof(V, I, N) => nthbyteof(V /Int 256, I, N -Int 1) when N >Int (I +Int 1) [concrete]
- rule nthbyteof(V, I, N) => V modInt 256 when N ==Int (I +Int 1) [concrete]
- syntax Map ::= Map "+Map" Map [function] //concatenates two maps if their keys are disjoint
- rule M +Map (K1 |-> V1) => M (K1 |-> V1)
- requires notBool #inKeys(M, K1)
- syntax Bool ::= #inKeys(Map, Int) [function]
- rule #inKeys(.Map, KEY) => false
- rule #inKeys((M:Map K0 |-> V0), K1) => true
- requires K0 ==K K1
- rule #inKeys((M:Map K0 |-> V0), K1) => #inKeys(M, K1)
- requires K0 =/=K K1
- rule 0 <=Int nthbyteof(V, I, N) => true
- rule nthbyteof(V, I, N) <Int 256 => true
- rule #asWord( nthbyteof(V, 0, 32)
- : nthbyteof(V, 1, 32)
- : nthbyteof(V, 2, 32)
- : nthbyteof(V, 3, 32)
- : nthbyteof(V, 4, 32)
- : nthbyteof(V, 5, 32)
- : nthbyteof(V, 6, 32)
- : nthbyteof(V, 7, 32)
- : nthbyteof(V, 8, 32)
- : nthbyteof(V, 9, 32)
- : nthbyteof(V, 10, 32)
- : nthbyteof(V, 11, 32)
- : nthbyteof(V, 12, 32)
- : nthbyteof(V, 13, 32)
- : nthbyteof(V, 14, 32)
- : nthbyteof(V, 15, 32)
- : nthbyteof(V, 16, 32)
- : nthbyteof(V, 17, 32)
- : nthbyteof(V, 18, 32)
- : nthbyteof(V, 19, 32)
- : nthbyteof(V, 20, 32)
- : nthbyteof(V, 21, 32)
- : nthbyteof(V, 22, 32)
- : nthbyteof(V, 23, 32)
- : nthbyteof(V, 24, 32)
- : nthbyteof(V, 25, 32)
- : nthbyteof(V, 26, 32)
- : nthbyteof(V, 27, 32)
- : nthbyteof(V, 28, 32)
- : nthbyteof(V, 29, 32)
- : nthbyteof(V, 30, 32)
- : nthbyteof(V, 31, 32)
- : .WordStack ) => V
- requires 0 <=Int V andBool V <Int pow256
- rule #asWord( nthbyteof(#unsigned(V), 0, 32)
- : nthbyteof(#unsigned(V), 1, 32)
- : nthbyteof(#unsigned(V), 2, 32)
- : nthbyteof(#unsigned(V), 3, 32)
- : nthbyteof(#unsigned(V), 4, 32)
- : nthbyteof(#unsigned(V), 5, 32)
- : nthbyteof(#unsigned(V), 6, 32)
- : nthbyteof(#unsigned(V), 7, 32)
- : nthbyteof(#unsigned(V), 8, 32)
- : nthbyteof(#unsigned(V), 9, 32)
- : nthbyteof(#unsigned(V), 10, 32)
- : nthbyteof(#unsigned(V), 11, 32)
- : nthbyteof(#unsigned(V), 12, 32)
- : nthbyteof(#unsigned(V), 13, 32)
- : nthbyteof(#unsigned(V), 14, 32)
- : nthbyteof(#unsigned(V), 15, 32)
- : nthbyteof(#unsigned(V), 16, 32)
- : nthbyteof(#unsigned(V), 17, 32)
- : nthbyteof(#unsigned(V), 18, 32)
- : nthbyteof(#unsigned(V), 19, 32)
- : nthbyteof(#unsigned(V), 20, 32)
- : nthbyteof(#unsigned(V), 21, 32)
- : nthbyteof(#unsigned(V), 22, 32)
- : nthbyteof(#unsigned(V), 23, 32)
- : nthbyteof(#unsigned(V), 24, 32)
- : nthbyteof(#unsigned(V), 25, 32)
- : nthbyteof(#unsigned(V), 26, 32)
- : nthbyteof(#unsigned(V), 27, 32)
- : nthbyteof(#unsigned(V), 28, 32)
- : nthbyteof(#unsigned(V), 29, 32)
- : nthbyteof(#unsigned(V), 30, 32)
- : nthbyteof(#unsigned(V), 31, 32)
- : .WordStack ) => #unsigned(V)
- requires #rangeSInt(256, V)
- rule #asWord( nthbyteof(keccakIntList(V), 0, 32)
- : nthbyteof(keccakIntList(V), 1, 32)
- : nthbyteof(keccakIntList(V), 2, 32)
- : nthbyteof(keccakIntList(V), 3, 32)
- : nthbyteof(keccakIntList(V), 4, 32)
- : nthbyteof(keccakIntList(V), 5, 32)
- : nthbyteof(keccakIntList(V), 6, 32)
- : nthbyteof(keccakIntList(V), 7, 32)
- : nthbyteof(keccakIntList(V), 8, 32)
- : nthbyteof(keccakIntList(V), 9, 32)
- : nthbyteof(keccakIntList(V), 10, 32)
- : nthbyteof(keccakIntList(V), 11, 32)
- : nthbyteof(keccakIntList(V), 12, 32)
- : nthbyteof(keccakIntList(V), 13, 32)
- : nthbyteof(keccakIntList(V), 14, 32)
- : nthbyteof(keccakIntList(V), 15, 32)
- : nthbyteof(keccakIntList(V), 16, 32)
- : nthbyteof(keccakIntList(V), 17, 32)
- : nthbyteof(keccakIntList(V), 18, 32)
- : nthbyteof(keccakIntList(V), 19, 32)
- : nthbyteof(keccakIntList(V), 20, 32)
- : nthbyteof(keccakIntList(V), 21, 32)
- : nthbyteof(keccakIntList(V), 22, 32)
- : nthbyteof(keccakIntList(V), 23, 32)
- : nthbyteof(keccakIntList(V), 24, 32)
- : nthbyteof(keccakIntList(V), 25, 32)
- : nthbyteof(keccakIntList(V), 26, 32)
- : nthbyteof(keccakIntList(V), 27, 32)
- : nthbyteof(keccakIntList(V), 28, 32)
- : nthbyteof(keccakIntList(V), 29, 32)
- : nthbyteof(keccakIntList(V), 30, 32)
- : nthbyteof(keccakIntList(V), 31, 32)
- : .WordStack ) => keccakIntList(V)
- rule ACCTCODE in SetItem( 1 )
- SetItem ( 2 )
- SetItem ( 3 )
- SetItem ( 4 )
- SetItem ( 5 )
- SetItem ( 6 )
- SetItem ( 7 )
- SetItem ( 8 )
- => false
- requires 9 <=Int ACCTCODE
- // for terms came from bytecode not via #hashedLocation
- rule keccak(WS) => keccakIntList(byteStack2IntList(WS))
- requires ( notBool #isConcrete(WS) )
- // andBool ( #sizeWordStack(WS) ==Int 32 orBool #sizeWordStack(WS) ==Int 64 )
- rule 0 <=Int keccakIntList(N) => true
- rule keccaktIntList(N) <Int pow256 => true
- rule #padToWidth(32, #asByteStack( #unsigned(V) )) => #asByteStackInWidth( #unsigned(V), 32)
- requires #rangeSInt(256, V)
- rule #padToWidth(32, #asByteStack(V)) => #asByteStackInWidth(V, 32)
- requires 0 <=Int V andBool V <Int pow256
- rule #padToWidth(32, #asByteStack( keccakIntList (V) )) => #asByteStackInWidth( keccakIntList (V), 32)
- // for Vyper
- rule #padToWidth(N, #asByteStack(#asWord(WS))) => WS
- requires #noOverflow(WS) andBool N ==Int #sizeWordStack(WS)
- // for Solidity
- rule #asWord(WS) /Int D => #asWord(#take(#sizeWordStack(WS) -Int log256Int(D), WS))
- requires D modInt 256 ==Int 0 andBool D >=Int 0
- andBool #sizeWordStack(WS) >=Int log256Int(D)
- andBool #noOverflow(WS)
- syntax Bool ::= #noOverflow ( WordStack ) [function]
- | #noOverflowAux ( WordStack ) [function]
- // -------------------------------------------------------
- rule #noOverflow(WS) => #sizeWordStack(WS) <=Int 32 andBool #noOverflowAux(WS)
- rule #noOverflowAux(W : WS) => 0 <=Int W andBool W <Int 256 andBool #noOverflowAux(WS)
- rule #noOverflowAux(.WordStack) => true
- syntax WordStack ::= #asByteStackInWidth ( Int, Int ) [function]
- | #asByteStackInWidthaux ( Int, Int, Int, WordStack ) [function]
- // -----------------------------------------------------------------------------------
- rule #asByteStackInWidth(X, N) => #asByteStackInWidthaux(X, N -Int 1, N, .WordStack)
- rule #asByteStackInWidthaux(X, I, N, WS) => #asByteStackInWidthaux(X, I -Int 1, N, nthbyteof(X, I, N) : WS) when I >Int 0
- rule #asByteStackInWidthaux(X, 0, N, WS) => nthbyteof(X, 0, N) : WS
- rule 0 +Int N => N
- rule N +Int 0 => N
- rule N -Int 0 => N
- rule 1 *Int N => N
- rule N *Int 1 => N
- rule 0 *Int _ => 0
- rule _ *Int 0 => 0
- rule N /Int 1 => N
- rule 0 |Int N => N
- rule N |Int 0 => N
- rule N |Int N => N
- rule 0 &Int N => 0
- rule N &Int 0 => 0
- rule N &Int N => N
- rule (I1 +Int I2) +Int I3 => I1 +Int (I2 +Int I3) when #isConcrete(I2) andBool #isConcrete(I3)
- rule (I1 +Int I2) -Int I3 => I1 +Int (I2 -Int I3) when #isConcrete(I2) andBool #isConcrete(I3)
- rule (I1 -Int I2) +Int I3 => I1 -Int (I2 -Int I3) when #isConcrete(I2) andBool #isConcrete(I3)
- rule (I1 -Int I2) -Int I3 => I1 -Int (I2 +Int I3) when #isConcrete(I2) andBool #isConcrete(I3)
- rule I1 &Int (I2 &Int I3) => (I1 &Int I2) &Int I3 when #isConcrete(I1) andBool #isConcrete(I2)
- // 0xffff...f &Int N = N
- rule MASK &Int N => N requires MASK ==Int (2 ^Int (log2Int(MASK) +Int 1)) -Int 1 // MASK = 0xffff...f
- andBool 0 <=Int N andBool N <=Int MASK
- // for gas calculation
- rule A -Int (#if C #then B1 #else B2 #fi) => #if C #then (A -Int B1) #else (A -Int B2) #fi
- rule (#if C #then B1 #else B2 #fi) -Int A => #if C #then (B1 -Int A) #else (B2 -Int A) #fi
- rule (#if C #then B1 #else B2 #fi) >Int A => true
- requires B1 >Int A andBool B2 >Int A
- rule (#if C #then B1 #else B2 #fi) >=Int A => true
- requires B1 >=Int A andBool B2 >=Int A
- rule A -Int A => 0
- rule bool2Word(A) |Int bool2Word(B) => bool2Word(A orBool B)
- rule bool2Word(A) &Int bool2Word(B) => bool2Word(A andBool B)
- rule bool2Word(A) ==K 0 => notBool(A)
- rule bool2Word(A) ==K 1 => A
- rule bool2Word(A) =/=K 0 => A
- rule bool2Word(A) =/=K 1 => notBool(A)
- rule chop(bool2Word(B)) => bool2Word(B)
- rule 0 <=Int chop(V) => true
- rule chop(V) <Int pow256 => true
- rule 0 <=Int keccak(V) => true
- rule keccak(V) <Int pow256 => true
- rule 0 <=Int X &Int Y => true requires 0 <=Int X andBool X <Int pow256 andBool 0 <=Int Y andBool Y <Int pow256
- rule X &Int Y <Int pow256 => true requires 0 <=Int X andBool X <Int pow256 andBool 0 <=Int Y andBool Y <Int pow256
- rule chop(I) => I requires 0 <=Int I andBool I <Int pow256
- rule #sizeWordStack ( _ , _ ) >=Int 0 => true [smt-lemma]
- rule #sizeWordStack ( WS , N:Int )
- => #sizeWordStack ( WS , 0 ) +Int N
- requires N =/=K 0
- [lemma]
- rule chop(#unsigned(W)) => #unsigned(W)
- requires #rangeSInt(256, W)
- rule #signed(#unsigned(W)) => W
- requires #rangeSInt(256, W)
- rule #unsigned(#signed(W)) => W
- requires #rangeUInt(256, W)
- rule W0 s<Word W1 => #signed(W0) <Word #signed(W1)
- rule #signed(X) ==K #signed(Y) => X ==K Y requires #rangeUInt(256,X) orBool #rangeUInt(256,Y)
- rule #unsigned(X) ==K #unsigned(Y) => X ==K Y requires #rangeSInt(256,X) orBool #rangeSInt(256,Y)
- rule A modInt pow160 => A
- requires #rangeAddress(A)
- syntax Bool ::= #notPrecompileAddress ( Int ) [function]
- // ---------------------------------------
- rule #notPrecompileAddress ( X ) => 9 <=Int X andBool #rangeAddress(X)
- // ABSTRACT SEMANTICS.k
- rule <k> LT W0 W1 => bool2Word(W0 <Int W1) ~> #push ... </k> [trusted]
- rule <k> GT W0 W1 => bool2Word(W0 >Int W1) ~> #push ... </k> [trusted]
- rule <k> EQ W0 W1 => bool2Word(W0 ==Int W1) ~> #push ... </k> [trusted]
- rule <k> ISZERO W => bool2Word(W ==Int 0 ) ~> #push ... </k> [trusted]
- //RULES MUST USE ==K and not ==Int
- //Warning: assumes injective hashing
- rule keccakIntList(A B .IntList) ==K keccakIntList(C D .IntList) => A ==Int C andBool B ==Int D
- rule keccakIntList(A B .IntList) =/=K keccakIntList(C D .IntList) => A =/=Int C orBool B =/=Int D
- rule keccakIntList(A B C .IntList) ==K keccakIntList(D E F .IntList) => A ==Int D andBool B ==Int E andBool C ==Int F
- rule keccakIntList(A B C .IntList) =/=K keccakIntList(D E F .IntList) => A =/=Int D orBool B =/=Int E orBool C =/=Int F
- rule keccakIntList(C) ==K A => false
- requires 0 <=Int A andBool A <=Int 20
- rule keccakIntList(C) =/=K A => true
- requires 0 <=Int A andBool A <=Int 20
- rule keccakIntList(C) +Int B ==K A => false
- requires 0 <=Int A andBool A <=Int 20
- andBool 0 <=Int B andBool B <=Int 20
- rule keccakIntList(C) +Int B =/=K A => true
- requires 0 <=Int A andBool A <=Int 20
- andBool 0 <=Int B andBool B <=Int 20
- rule A ==K keccakIntList(C) +Int B => false
- requires 0 <=Int A andBool A <=Int 20
- andBool 0 <=Int B andBool B <=Int 20
- rule A =/=K keccakIntList(C) +Int B => true
- requires 0 <=Int A andBool A <=Int 20
- andBool 0 <=Int B andBool B <=Int 20
- rule keccakIntList(C) +Int B ==K keccakIntList(A) => false
- requires 0 <=Int B andBool B <=Int 20
- rule keccakIntList(C) +Int B =/=K keccakIntList(A) => true
- requires 0 <=Int B andBool B <=Int 20
- rule keccakIntList(A) +Int B ==K keccakIntList(A) +Int C => false
- requires B =/=Int C
- rule keccakIntList(A) +Int B =/=K keccakIntList(A) +Int C => true
- requires B =/=Int C
- rule keccakIntList(A) +Int B ==K keccakIntList(C) +Int D => false
- requires B =/=Int C
- rule keccakIntList(A) +Int B =/=K keccakIntList(C) +Int D => true
- requires B =/=Int C
- rule keccakIntList(A) ==K keccakIntList(C) +Int B => false
- requires 0 <=Int B andBool B <=Int 20
- rule keccakIntList(A) =/=K keccakIntList(C) +Int B => true
- requires 0 <=Int B andBool B <=Int 20
- rule A ==K keccakIntList(C) => false
- requires 0 <=Int A andBool A <=Int 20
- rule A =/=K keccakIntList(C)=> true
- requires 0 <=Int A andBool A <=Int 20
- // src/lemmas.k.md
- // src/storage.md
- syntax Int ::= "#Token.balances" "[" Int "]" [function]
- // -----------------------------------------------
- // doc: The token balance of `$0`
- rule #Token.balances[A] => #hashedLocation("Solidity", 0, A)
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement