flashloan-rs 0.2.1

Minimal Multicall3 Flashloan Module
Documentation
/// @title SSTORE2
/// @notice SPDX-License-Identifier: MIT
/// @author asnared <https://github.com/abigger87>
/// @notice Faster & cheaper contract key-value storage for Ethereum Contracts
/// @notice Adapted from 0xsequence/sstore2 (https://github.com/0xsequence/sstore2)

#include "./Bytecode.huff"
#include "./CommonErrors.huff"

#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

/// @notice Stores `_data` and returns `pointer` as key for later retrieval
/// @dev The pointer is a contract address with `_data` as code
/// @param {_data} [bytes memory] to be written
/// @return pointer Pointer to the written `_data`
#define macro SSTORE2_WRITE() = takes (0) returns (1) {
    // Load the data memory pointer
    0x04 calldataload                    // [&_data]
    dup1 0x04 add calldataload swap1     // [&_data, _data.length]

    // Create the contract creation code
    CREATION_CODE_FOR()               // [&_data, _data.length]

    // Deploy the contract
    swap1                             // [_data.length, &_data]
    0x0f add                          // [size, &_data]
    0x00                              // [offset, size, &_data]
    0x00                              // [value, offset, size, &_data]
    create                            // [address, &_data]

    // Check that the address is non-zero
    dup1 iszero iszero success jumpi  // [address, &_data]
    CREATE_FAILED(0x00)
    success:

    // Clean the stack and return the address
    swap1 pop                         // [address]
}

/// @notice Reads the contents of the `_pointer` code as data, skips the first byte
/// @dev The function is intended for reading pointers generated by `write`
/// @param _pointer to be read
/// @return data read from `_pointer` contract
#define macro SSTORE2_READ() = takes (1) returns (1) {
  // Input Stack: [_pointer]
  // We start at 1 because the first byte are zeros to prevent the contract from being called
  0x01                                // [_start, _pointer]
  [TYPE_UINT_256_MAX]                 // [_end, _start, _pointer]
  swap2                               // [_pointer, _start, _end]
  CODE_AT()                           // [code]
}

/// @notice Reads the contents of the `_pointer` code as data, skips the first byte
/// @dev The function is intended for reading pointers generated by `write`
/// @param _pointer to be read
/// @param _start number of bytes to skip
/// @return data read from `_pointer` contract
#define macro SSTORE2_READ_AT() = takes (2) returns (1) {
  // Input Stack: [_pointer, _start]
  swap1                               // [_start, _pointer]
  [TYPE_UINT_256_MAX]                 // [_end, _start, _pointer]
  swap2                               // [_pointer, _start, _end]
  CODE_AT()                           // [code]
}

/// @notice Reads the contents of the `_pointer` code as data, skips the first byte
/// @dev The function is intended for reading pointers generated by `write`
/// @param _pointer to be read
/// @param _start number of bytes to skip
/// @param _end index before which to end extraction
/// @return data read from `_pointer` contract
#define macro SSTORE2_READ_BETWEEN() = takes (3) returns (1) {
  // Input Stack: [_pointer, _start, _end]
  CODE_AT()                           // [code]
}