datahaven/operator/precompiles/batch/Batch.sol
Steve Degosserie 757a99b7c6
feat: Add Moonbeam Batch precompile (#138)
## Summary

This PR adds Moonbeam's Batch precompile to DataHaven, enabling
efficient batching of multiple EVM transactions in a single call. This
implementation follows Moonbeam's exact architecture and provides
significant gas savings for batch operations.

## Key Features

### Batch Precompile Functions
- **`batchSome(address[], uint256[], bytes[], uint64[])`**: Execute
multiple calls, continuing on failures
- **`batchSomeUntilFailure(address[], uint256[], bytes[], uint64[])`**:
Execute calls until first failure
- **`batchAll(address[], uint256[], bytes[], uint64[])`**: Execute all
calls, reverting if any fail

### Technical Implementation
- **Address**: `0x0808` (2056 in decimal)
- **Access Control**: Restricted nesting with `SubcallWithMaxNesting<2>`
- **Self-recursion**: Only the Batch precompile can call itself
(`OnlyFrom<AddressU64<2056>>`)
- **Gas Management**: Proper gas estimation and refund handling
- **Error Handling**: Comprehensive revert reasons and event logging

Depends on #137

---------

Co-authored-by: Ahmad Kaouk <ahmadkaouk.93@gmail.com>
2025-09-05 19:24:09 +02:00

82 lines
3.7 KiB
Solidity

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.3;
/// @dev The Batch contract's address.
address constant BATCH_ADDRESS = 0x0000000000000000000000000000000000000808;
/// @dev The Batch contract's instance.
Batch constant BATCH_CONTRACT = Batch(BATCH_ADDRESS);
/// @author The Moonbeam Team
/// @title Batch precompile
/// @dev Allows to perform multiple calls throught one call to the precompile.
/// Can be used by EOA to do multiple calls in a single transaction.
/// @custom:address 0x0000000000000000000000000000000000000808
interface Batch {
/// @dev Batch multiple calls into a single transaction.
/// All calls are performed from the address calling this precompile.
///
/// In case of one subcall reverting following subcalls will still be attempted.
///
/// @param to List of addresses to call.
/// @param value List of values for each subcall. If array is shorter than "to" then additional
/// calls will be performed with a value of 0.
/// @param callData Call data for each `to` address. If array is shorter than "to" then
/// additional calls will be performed with an empty call data.
/// @param gasLimit Gas limit for each `to` address. Use 0 to forward all the remaining gas.
/// If array is shorter than "to" then the remaining gas available will be used.
/// @custom:selector 79df4b9c
function batchSome(
address[] memory to,
uint256[] memory value,
bytes[] memory callData,
uint64[] memory gasLimit
) external;
/// @dev Batch multiple calls into a single transaction.
/// All calls are performed from the address calling this precompile.
///
/// In case of one subcall reverting, no more subcalls will be executed but
/// the batch transaction will succeed. Use batchAll to revert on any subcall revert.
///
/// @param to List of addresses to call.
/// @param value List of values for each subcall. If array is shorter than "to" then additional
/// calls will be performed with a value of 0.
/// @param callData Call data for each `to` address. If array is shorter than "to" then
/// additional calls will be performed with an empty call data.
/// @param gasLimit Gas limit for each `to` address. Use 0 to forward all the remaining gas.
/// If array is shorter than "to" then the remaining gas available will be used.
/// @custom:selector cf0491c7
function batchSomeUntilFailure(
address[] memory to,
uint256[] memory value,
bytes[] memory callData,
uint64[] memory gasLimit
) external;
/// @dev Batch multiple calls into a single transaction.
/// All calls are performed from the address calling this precompile.
///
/// In case of one subcall reverting, the entire batch will revert.
///
/// @param to List of addresses to call.
/// @param value List of values for each subcall. If array is shorter than "to" then additional
/// calls will be performed with a value of 0.
/// @param callData Call data for each `to` address. If array is shorter than "to" then
/// additional calls will be performed with an empty call data.
/// @param gasLimit Gas limit for each `to` address. Use 0 to forward all the remaining gas.
/// If array is shorter than "to" then the remaining gas available will be used.
/// @custom:selector 96e292b8
function batchAll(
address[] memory to,
uint256[] memory value,
bytes[] memory callData,
uint64[] memory gasLimit
) external;
/// Emitted when a subcall succeeds.
event SubcallSucceeded(uint256 index);
/// Emitted when a subcall fails.
event SubcallFailed(uint256 index);
}