Analysis Tools ============== Here, we define analysis tools specific to EVM. These tools are defined as extensions of the semantics, utilizing the underlying machinery to do execution. One benefit of K is that we do not have to re-specify properties about the operational behavior in our analysis tools; instead we can take the operational behavior directly. .. code-block:: k requires "evm.k" module EVM-ANALYSIS imports EVM Gas Analysis ------------ Gas analysis tools will help in determining how much gas to call a contract with given a specific input. This can be used to ensure that computation will finish without throwing an exception and rolling back state. Here we provide a simplistic gas analysis tool (which just returns an approximation of the gas used for each basic block). This tool should be extended to take advantage of the symbolic execution engine so that we can provide proper bounds on the gas used. - The mode ``GASANALYZE`` performs gas analysis of the program instead of executing normally. .. code-block:: k syntax Mode ::= "GASANALYZE" We'll need to make summaries of the state which collect information about how much gas has been used. - ``#beginSummary`` appends a new (unfinished) summary entry in the ``analysis`` cell under the key ``"gasAnalyze"``. - ``#endSummary`` looks for an unfinished summary entry by the key ``"gasAnalyze"`` and performs the substraction necessary to state how much gas has been used since the corresponding ``#beginSummary``. .. code-block:: k syntax Summary ::= "{" Int "|" Int "|" Int "}" | "{" Int "==>" Int "|" Int "|" Int "}" // -------------------------------------------------------- syntax InternalOp ::= "#beginSummary" // ------------------------------------- rule #beginSummary => . ... PCOUNT GAVAIL MEMUSED ... "blocks" |-> ((.List => ListItem({ PCOUNT | GAVAIL | MEMUSED })) REST) ... syntax KItem ::= "#endSummary" // ------------------------------ rule (#end => .) ~> #endSummary ... rule #endSummary => . ... PCOUNT GAVAIL MEMUSED ... "blocks" |-> (ListItem({ PCOUNT1 | GAVAIL1 | MEMUSED1 } => { PCOUNT1 ==> PCOUNT | GAVAIL1 -Int GAVAIL | MEMUSED -Int MEMUSED1 }) REST) ... - In ``GASANALYZE`` mode, summaries of the state are taken at each ``#gasBreaks`` opcode, otherwise execution is as in ``NORMAL``. .. code-block:: k rule GASANALYZE #next => #setMode NORMAL ~> #execTo #gasBreaks ~> #setMode GASANALYZE ... PCOUNT ... PCOUNT |-> OP ... requires notBool (OP in #gasBreaks) rule GASANALYZE #next => #endSummary ~> #setPC (PCOUNT +Int 1) ~> #setGas 1000000000 ~> #beginSummary ~> #next ... PCOUNT ... PCOUNT |-> OP ... requires OP in #gasBreaks syntax Set ::= "#gasBreaks" [function] // -------------------------------------- rule #gasBreaks => (SetItem(JUMP) SetItem(JUMPI) SetItem(JUMPDEST)) syntax InternalOp ::= "#setPC" Int | "#setGas" Int // ----------------------------------- rule #setPC PCOUNT => . ... _ => PCOUNT rule #setGas GAVAIL => . ... _ => GAVAIL - ``#gasAnalyze`` analyzes the gas of a chunk of code by setting up the analysis state appropriately and then setting the mode to ``GASANALYZE``. .. code-block:: k syntax KItem ::= "#gasAnalyze" // ------------------------------ rule #gasAnalyze => #setGas 1000000000 ~> #beginSummary ~> #setMode GASANALYZE ~> #execute ~> #endSummary ... _ => 0 _ => 1000000000 _ => ("blocks" |-> .List) endmodule