feat(v2): Safe Operations with Low Level Integers
refcell opened this issue · comments
Description
Pending #103, implementations for safely operating on low level integer types in huff can be done.
As detailed by @AmadiMichael:
Example: an extra macro in the safeMath library called
SAFE_ADD_TYPE()
, the same asSAFE_ADD()
but would take a third stack input which is the max value of the intended type to cast the result into
/// a rewrite of safe add with max type
/// @notice Adds two numbers and reverts on overflow
#define macro SAFE_ADD_TYPE() = takes (3) returns (1) {
// input stack // [num1, num2, typeMax]
dup2 // [num2, num1, num2, typeMax]
add // [result, num2, typeMax]
dup1 // [result, result, num2, typeMax]
swap2 // [num2, result, result, typeMax]
gt // [is_overflow, result, typeMax]
iszero // [is_not_overflow, result, typeMax]
is_not_overflow jumpi // [result, typeMax]
[ARITHMETIC_OVERFLOW] PANIC()
is_not_overflow: // [result, typeMax]
swap1 // [typeMax, result]
dup2 // [result, typeMax, result]
gt // [is_type_overflow, result]
iszero // [is_not_type_overflow, result]
is_not_type_overflow jumpi // [result]
[ARITHMETIC_OVERFLOW] PANIC()
is_not_type_overflow:
}
This can help in safe calculation of values of lower types like uint128 etc. After the initial overflow check (which accounts for only 256 bits) there's a check to ensure it doesn't overflow from the type you intend to keep it within.
someone can call this with
#include "utils/Constants.huff"
...
#define macro ADD_UINT128() = takes(0) returns(1) {
[__UINT128_MAX] // [Uint128Max]
0x01 // [0x01, uint128Max]
0x02 // [0x02, 0x01, uint128Max]
SAFE_ADD_TYPE() // [result]
}
Returns a result in uint128
This will revert if trying to add numbers where either of them is higher than the max of result's type.