3

In the Solidity documentation is stated that:

The evaluation order of expressions is not specified (more formally, the order in which the children of one node in the expression tree are evaluated is not specified, but they are of course evaluated before the node itself). It is only guaranteed that statements are executed in order and short-circuiting for boolean expressions is done. See Order of Precedence of Operators for more information.

I want to better understand this point with the aid of an example. Let's say I have a smart contract with a function g that computes the sum of two inputs.

g(uint a, uint b) {
   return a + b;
}

...
uint res = g(x + 2, (x++) + 3); 

Let us further suppose that x is equals to 5. So, since the evaluation order is not guaranteed it is possible that the compiler will compile this instruction into two different piece of code: either the actual parameter for a is evaluated before the one for b or the actual parameter for b before the one of a. This will give raise to two different calls with different result:

  • g(7, 8)
  • g(8, 8)

Is this example correct? Why is this unsafe behavior kept in a language that is supposed to enable to write safe smart contracts?

  • The core of the compiler, which handles regular-language syntax, has most likely been extracted from an already-existing (and thoroughly-verified) source code. You wouldn't wanna write that from scratch, right? I mean, security level would drastically decrease just as a result of that. So this basic syntax is supported, but it doesn't mean that one should use it (in fact, not only in Solidity, but in any language). – goodvibration Mar 25 at 12:46
  • I do agree with you that this example is too artificial and too trivial. However there are surely less evident examples, in which changing the order of evaluation may lead to issues (the "wiz-in-wicks" effect) research.cs.wisc.edu/wpis/papers/wysinwyx.final.pdf . Moreover, the experience of many decades, shows that relying on developers for security is not always a good idea. – Briomkez Mar 25 at 13:55
  • If you know of such examples, then maybe you should post them instead of something like (x++) + 3, which is not something that anyone is ever likely to use (other than giving it as an example of how not to write code). – goodvibration Mar 25 at 14:06
  • I found also this github issue that provide additional details github.com/ethereum/solidity/issues/4579. Sorry, I did not mean to be rough. My problem is that I want to perform some source code analysis, and this behavior require me to consider all permutations of parameter evaluation to be sound, which is an undesired characteristic for a source code analyzer because it looses precision. Moreover, I cannot understand how can undefined behaviors find place in a language such as Solidity that should be devoted to predictability to avoid unforenseen consequences. – Briomkez Mar 25 at 14:32
0

In your example there are two separate expressions: x + 2 and (x++) + 3, but documentation you quoted probably refers to subexpressions of bigger expression. So, in you case order of execution is probably guaranteed, though Solidity behavior is not well defined.

I would say that better example for what this documentation phrase means is that the result of the following code is ambiguous:

function foo () public pure returns (uint) {
  uint x = 5;
  return x * x++; // Could be 25 or 30
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.