huff-language / huffmate

A library of modern, hyper-optimized, and extensible Huff contracts with extensive testing and documentation built by Huff maintainers.
https://github.com/pentagonxyz/huffmate
MIT License
430 stars 55 forks source link

Add constants utils #103

Closed AmadiMichael closed 1 year ago

AmadiMichael commented 1 year ago

By importing utils/constants.huff. Cleaner code and helpers around other dynamic constants common in solidity and other higher level evm language.

The constant wrapper is an example of how it can be used and also has full test coverage.

AmadiMichael commented 1 year ago

This looks nice and well executed ! Idk if this is that useful though and that it should be part of huffmate, curious to see other's opinions.

currently there's no safe library for working with lower integer types in huff, constants can help...

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.

AmadiMichael commented 1 year ago

Hello guys, would love to hear your thoughts on if constants.huff fits into huffmate and suggestions too. Thank you

AmadiMichael commented 1 year ago

I think this is useful, happy to include efficient utilities people will use. Can you fix the merge conflicts and we'll get this merged?

Done 🫡