4

I think I found a EVM bug regarding integer overflow:

The below works:

uint16 a = 1;
uint256 b = a * 0.001 ether;

But, the below fails due to the overflow:

uint16 a = 1000;
uint256 b = a * 0.001 ether;

To my understandings, for the multiplication of uints with different precisions, it should cast the smaller one (uint16 in the above example) to the bigger one (uint256)

1 Answer 1

8

It's not a bug, that's the expected behavior, let me explain why.

First It doesn't cast in the order you mentioned, from the docs:

  • If the type of the right operand can be implicitly converted to the type of the left operand, use the type of the left operand,
  • if the type of the left operand can be implicitly converted to the type of the right operand, use the type of the right operand,
  • otherwise, the operation is not allowed.

If we apply this to your code, a is a type of uint16 with max value 65535, 0.001 ether has no explicit type, the compiler will implicitly give it the smallest datatype it accepts i.e uint56 with a max value of 72057594037927935.

Now we have uint16 and uint56 and the value of multiplying 1000 with 0.001 ether is 1000000000000000000 which is a type of uint64.

Let's back to the docs and see where our case fits,

  • (try the left operand type on the right operand ) fails because the result is higher than uint16
  • (try the right operand type on the left operand ) fails because the result is higher than uint56

The operation is not allowed so it reverts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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