flashloan-rs 0.2.0

Minimal Multicall3 Flashloan Module
Documentation
/// @title TSOwnable
/// @notice SPDX-License-Identifier: MIT
/// @author merkleplant (modified by @devtooligan)
/// @author asnared <https://github.com/abigger87>
/// @notice An Ownable Implementation using Two-Step Transfer Pattern

#include "./Address.huff"
#include "./CommonErrors.huff"
#include "../auth/NonPayable.huff"

// External Interface

/// @notice Returns the current owner address.
#define function owner() view returns (address)

/// @notice Returns the current pending owner address.
#define function pendingOwner() view returns (address)

/// @notice Sets the pending owner address.
/// @dev Only callable by owner.
#define function setPendingOwner(address) nonpayable returns ()

/// @notice Accepts the ownership.
/// @dev Only callable by pending owner.
#define function acceptOwnership() nonpayable returns ()

/// @notice Emitted when new owner set.
#define event NewOwner(address, address)

/// @notice Emitted when new pending owner set.
#define event NewPendingOwner(address, address)

// Storage

/// @notice Owner Storage Slot
#define constant OWNER_SLOT = FREE_STORAGE_POINTER()

/// @notice Pending Owner Storage Slot
#define constant PENDING_OWNER_SLOT = FREE_STORAGE_POINTER()

/// @notice Inner TSOwnable Constructor
#define macro TSOWNABLE_CONSTRUCTOR() = takes (0) returns (0) {
    // Store msg.sender as owner
    caller [OWNER_SLOT] sstore          // []
}

/// @notice Only Owner Modifier
#define macro ONLY_OWNER_MODIFIER() = takes (0) returns (0) {
    [OWNER_SLOT] sload                      // [owner]
    caller eq authed jumpi                  // []
    ONLY_OWNER(0x00)                        // []
    authed:                                 // []
}

/// @notice Only Pending Owner Modifier
#define macro ONLY_PENDING_OWNER_MODIFIER() = takes (0) returns (0) {
    [PENDING_OWNER_SLOT] sload              // [pending_owner]
    caller eq                               // [msg.sender == pending_owner]
    authed jumpi                            // []
    ONLY_PENDING_OWNER(0x00)                // []
    authed:                                 // []
}

// Mutating Functions

/// @notice Set Pending Owner
/// @param newOwner The address of the new pending owner
#define macro OWNABLE_SET_PENDING_OWNER() = takes (0) returns (0) {
    NON_PAYABLE()                               // []
    ONLY_OWNER_MODIFIER()                       // []

    // Read argument and mask to address
    0x04 calldataload MASK_ADDRESS()            // [newOwner]

    // Revert if address equals owner
    dup1 caller                                 // [owner, newOwner, newOwner]
    eq iszero set jumpi                         // [newOwner]
    ALREADY_OWNER(0x00)                         // []
    set:                                        // [newOwner]

    // Duplicate address on stack
    dup1                                        // [newOwner, newOwner]

    // Emit NewPendingOwner event
    [OWNER_SLOT] sload                          // [owner, newOwner, newOwner]
    __EVENT_HASH(NewPendingOwner) 0x00 0x00     // [offset, size, sig, owner, newOwner, newOwner]
    log3                                        // [newOwner]

    // Store address as pending owner
    [PENDING_OWNER_SLOT] sstore                 // []

    // Stop execution
    stop
}

/// @notice Accept Ownership
/// @notice Allows the pending owner to become the owner
#define macro OWNABLE_ACCEPT_OWNERSHIP() = takes (0) returns (0) {
    NON_PAYABLE()                               // []
    ONLY_PENDING_OWNER_MODIFIER()               // []

    // Emit NewOwner event
    caller [OWNER_SLOT] sload                   // [owner, pending_owner]
    __EVENT_HASH(NewOwner) 0x00 0x00            // [offset, size, sig, owner, pending_owner]
    log3                                        // []

    // Store msg.sender as owner
    caller [OWNER_SLOT] sstore                  // []

    // Clear pending owner
    0x00 [PENDING_OWNER_SLOT] sstore            // []

    // Stop execution
    stop
}

// View Functions

/// @notice Get Owner
/// @notice Returns the current owner
#define macro OWNABLE_GET_OWNER() = takes (0) returns (0) {
    NON_PAYABLE()                   // []
    [OWNER_SLOT] sload              // [owner]
    0x00 mstore                     // []
    0x20 0x00 return                // []
}

/// @notice Get Pending Owner
/// @notice Returns the current pending owner
#define macro OWNABLE_GET_PENDING_OWNER() = takes (0) returns (0) {
    NON_PAYABLE()                   // []
    [PENDING_OWNER_SLOT] sload      // [pending_owner]
    0x00 mstore                     // []
    0x20 0x00 return                // []
}

// Function Dispatching
#define macro TSOWNABLE_MAIN() = takes (1) returns (1) {
    // Input stack: [sig]
    // Output stack: [sig]

    dup1 __FUNC_SIG(setPendingOwner)    eq set_pending_owner jumpi
    dup1 __FUNC_SIG(acceptOwnership)    eq accept_ownership jumpi
    dup1 __FUNC_SIG(owner)              eq get_owner jumpi
    dup1 __FUNC_SIG(pendingOwner)       eq get_pending_owner jumpi

    // Bubble up to the parent macro
    no_match jump

    set_pending_owner:
        OWNABLE_SET_PENDING_OWNER()
    accept_ownership:
        OWNABLE_ACCEPT_OWNERSHIP()
    get_owner:
        OWNABLE_GET_OWNER()
    get_pending_owner:
        OWNABLE_GET_PENDING_OWNER()

    no_match:
}