Skip to content
This repository was archived by the owner on Apr 3, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/
@prb/math/=node_modules/@prb/math/
forge-std/=node_modules/forge-std/
solady/=node_modules/solady/
forge-std/=node_modules/forge-std/
solady/=node_modules/solady/
21 changes: 17 additions & 4 deletions src/abstracts/Batch.sol
Comment thread
smol-ninja marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// solhint-disable no-inline-assembly
pragma solidity >=0.8.22;

import { IBatch } from "../interfaces/IBatch.sol";
import { Errors } from "../libraries/Errors.sol";

/// @title Batch
/// @notice See the documentation in {IBatch}.
/// @dev Forked from: https://github.com/boringcrypto/BoringSolidity/blob/master/contracts/BoringBatchable.sol
abstract contract Batch is IBatch {
/*//////////////////////////////////////////////////////////////////////////
USER-FACING NON-CONSTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/// @inheritdoc IBatch
function batch(bytes[] calldata calls) external payable override {
/// @dev Since `msg.value` can be reused across calls, be VERY CAREFUL when using it. Refer to
/// https://paradigm.xyz/2021/08/two-rights-might-make-a-wrong for more information.
function batch(bytes[] calldata calls) external payable override returns (bytes[] memory results) {
uint256 count = calls.length;
results = new bytes[](count);

for (uint256 i = 0; i < count; ++i) {
(bool success, bytes memory result) = address(this).delegatecall(calls[i]);

// Check: If the delegatecall failed, load and bubble up the revert data.
if (!success) {
revert Errors.BatchError(result);
assembly {
// Get the length of the result stored in the first 32 bytes.
let resultSize := mload(result)

// Forward the pointer by 32 bytes to skip the length argument, and revert with the result.
revert(add(32, result), resultSize)
}
}

// Push the result into the results array.
results[i] = result;
}
}
}
7 changes: 5 additions & 2 deletions src/interfaces/IBatch.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ pragma solidity >=0.8.22;

/// @notice This contract implements logic to batch call any function.
interface IBatch {
/// @notice Allows batched call to self, `this` contract.
/// @notice Allows batched calls to self, i.e., `this` contract.
/// @dev Since `msg.value` can be reused across calls, be VERY CAREFUL when using it. Refer to
/// https://paradigm.xyz/2021/08/two-rights-might-make-a-wrong for more information.
/// @param calls An array of inputs for each call.
function batch(bytes[] calldata calls) external payable;
/// @return results An array of results from each call. Empty when the calls do not return anything.
function batch(bytes[] calldata calls) external payable returns (bytes[] memory results);
}
1 change: 0 additions & 1 deletion tests/fork/Fork.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pragma solidity >=0.8.22;

import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ISablierFlow } from "src/interfaces/ISablierFlow.sol";
import { SablierFlow } from "src/SablierFlow.sol";

import { Base_Test } from "../Base.t.sol";
Expand Down
Loading