huff-language / huffmate

A library of modern, hyper-optimized, and extensible Huff contracts with extensive testing and documentation built by Huff maintainers.

Home Page:https://github.com/pentagonxyz/huffmate

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 as SAFE_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.