flashloan-rs 0.2.3

Minimal Multicall3 Flashloan Module
Documentation
/// @title SafeMath
/// @notice SPDX-License-Identifier: MIT
/// @author kadenzipfel <https://github.com/kadenzipfel>
/// @notice Math module over Solidity's arithmetic operations with safety checks
/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol)

#include "../utils/Errors.huff"

// Interface
#define function safeAdd(uint256,uint256) pure returns (uint256)
#define function safeSub(uint256,uint256) pure returns (uint256)
#define function safeMul(uint256,uint256) pure returns (uint256)
#define function safeDiv(uint256,uint256) pure returns (uint256)
#define function safeMod(uint256,uint256) pure returns (uint256)

/// @notice Adds two numbers and reverts on overflow
#define macro SAFE_ADD() = takes (2) returns (1) {
    // input stack          // [num1, num2]
    dup2                    // [num2, num1, num2]
    add                     // [result, num2]
    dup1                    // [result, result, num2]
    swap2                   // [num2, result, result]
    gt                      // [is_overflow, result]
    iszero                  // [is_not_overflow, result]
    is_not_overflow jumpi   // [result]
        [ARITHMETIC_OVERFLOW] PANIC()
    is_not_overflow:        // [result]
}

/// @notice Subtracts two numbers and reverts on underflow
#define macro SAFE_SUB() = takes (2) returns (1) {
    // input stack          // [num1, num2]
    dup1                    // [num1, num1, num2]
    dup3                    // [num2, num1, num1, num2]
    gt                      // [is_underflow, num1, num2]
    iszero                  // [is_not_underflow, num1, num2]
    is_not_underflow jumpi  // [num1, num2]
        [ARITHMETIC_OVERFLOW] PANIC()
    is_not_underflow:       // [num1, num2]
    sub                     // [result]
}

/// @notice Multiplies two numbers and reverts on overflow
#define macro SAFE_MUL() = takes (2) returns (1) {
    // input stack              // [num1, num2]
    dup1                        // [num1, num1, num2]
    is_not_zero jumpi           // [num1, num2]
        mul                     // [result]
        0x01 is_not_overflow jumpi
    is_not_zero:                // [num1, num2]
    dup2                        // [num2, num1, num2]
    dup2                        // [num1, num2, num1, num2]
    mul                         // [result, num1, num2]
    swap1                       // [num1, result, num2]
    dup2                        // [result, num1, result, num2]
    div                         // [div_check, result, num2]
    swap1                       // [result, div_check, num2]
    swap2                       // [num2, div_check, result]
    eq                          // [is_not_overflow, result]
    is_not_overflow jumpi       // [result]
        [ARITHMETIC_OVERFLOW] PANIC()
    is_not_overflow:
}

/// @notice Divides two numbers and reverts on division by zero
#define macro SAFE_DIV() = takes (2) returns (1) {
    // input stack          // [num1, num2]
    dup2                    // [num2, num1, num2]
    0x00 swap1              // [num2, 0, num1, num2]
    gt                      // [is_not_div_zero, num1, num2]
    is_not_div_zero jumpi
        [DIVIDE_BY_ZERO] PANIC()
    is_not_div_zero:
    div                     // [result]
}

/// @notice Divides two numbers and reverts on division by zero or modulo zero
#define macro SAFE_MOD() = takes (2) returns (1) {
    // input stack          // [num1, num2]
    dup2                    // [num2, num1, num2]
    0x00 swap1              // [num2, 0, num1, num2]
    gt                      // [is_not_mod_zero, num1, num2]
    is_not_mod_zero jumpi
        [ARITHMETIC_OVERFLOW] PANIC()
    is_not_mod_zero:
    mod                     // [result]
}