How to deal with integer overflows in PyTeal

One of Tinyman’s latest issues has been integer overflows.

Questions:

  1. Does PyTeal’s interpreter have functionality that deals with integer overflows or do we need to take them into account when designing a smart contract?

  2. If we were to deal with them on our own (in the case of multiplication/division), how could we go about it?

Ideas in the case of a multiplication overflow:

if multiplication >= 2**64, then: do something about it.

  • I don’t really know what “do something about it” means in the context of an overflow.

  • In the case of divisions, I have no idea as to how to deal with overflows.

Any ideas?

PyTEAL doesn’t perform checks on overflows, since PyTEAL compiler just generates TEAL source code from PyTEAL expressions (representing abstract syntax trees). PyTEAL does not execute TEAL programs on compiling.

The AVM default panics on overflows, underflows or division by zero. If panic is acceptable as expected application’s behaviour then you can stick with the default AVM reaction in this situations.

Otherwise you should:

  1. Impose limitations on variables involved in operations that can possibly result in an overflow, underflow or division by zero;

or

  1. Catch all the operations on which an overflow, underflow or division by zero may occur and handle it accordingly (differently from just panic as default);

Question 1) So the Tinyman issue was caused by overflow panics raised by the AVM?

Question 2) In the case of a panic, how can it be handled inside of PyTeal. Is there a .catch() like function/opcode?

I ask these questions because in the Runtime report for this bug, they mentioned a check for leading zeroes in the case of an overflow.

Skip to the Overflow Issue in the Price Oracle section.

Tinyman’s issue, occurred on Jan 1st/2nd, has nothing to do with the overflow condition.

This being said, there was a known minor corner case in Tinyman’s Price Oracle, for specific conditions of liquidity, in which an overflow could result in Tinyman’s LPs lock. This overflow condition has been addressed and solved in latest Tinyman’s contracts update.

You have to code your check by yourself, there is no Try/Catch like structure in PyTEAL nor as native TEAL opcode. If you come up with a general implementation, useful for other PyTEAL users, you can consider proposing it in PyTEAL-utils.

Hey Cusma,

Thanks for the quick responses.

I am talking specifically about the Tinyman’s Price Oracle bug. They addressed it here:


**Disclaimer: this screenshot was taken from the Runtime Verification GitHub repository: publications/Tinyman-security-review.pdf at main · runtimeverification/publications · GitHub **

They talk about “wide multiplication” and checking for zeroes in high order bits. I was wondering if you could maybe elaborate on this point.

The normal multiplication opcode * of the previous version has now been substituted with the wide multiplication mulw opcode, documented here.

Among other things, with this opcode you can check if the results of the multiplication is greater than an uint64, an act accordingly.

You can review the actual updated implementation by Tinyman here: https://github.com/tinymanorg/tinyman-contracts-v1/blob/main/contracts/validator_approval.teal#L395

2 Likes

To add on @cusma’s excellent response, when working with fixed-size integer in critical software, you should be doing a semi-formal or formal range analysis.

Concretely, for any integer x in your smart contract, you want to show that it is always between values a and b, where a and b can be represented by the integer chosen (i.e., they fit in 64 bits)
To do that semi-formally, you first show that when initializing the smart contract, this is the case. (A trivial example is when the integer is 0 at the beginning and the lower bound a is also 0). Then you analyse all possible calls to the smart contract and show the following invariant:

if the integer x was between a and b before the call, then during the call and after the call, the integer x stays between a and b
This ensures that at any point x stays between a and b.

This analysis is complex and time-consuming but I believe it is of the outmost importance in critical software, such as smart contracts.

This kind of analysis is done in plane or rocket embedded software for example (often in a slightly more formal and automated way).

If you are dealing with floating point (which TEAL does not have), the analysis is even more complex, as floating point not only have issues with bounds (max and min values) but also with precision. But this is another story. Here, you would most likely need an expert to deal with a critical software with floating point.

2 Likes