MultiCall v3

Batch multiple contract calls into a single transaction for improved gas efficiency.

MultiCall v3 is a utility contract that allows you to batch multiple contract calls into a single transaction, significantly reducing gas costs and improving efficiency for applications that need to make multiple reads or writes.

Contract Details

Contract Address: 0xcA11bde05977b3631167028862bE2a173976CA11

Source Code: GitHub Repository

Network: Nexera Testnet (and 70+ other chains)

Key Features

  • Gas Optimization: Batch multiple calls to reduce transaction overhead
  • Flexible Execution: Support for both successful and failed call handling
  • Value Transfers: Execute calls with ETH value transfers
  • Backwards Compatibility: Compatible with Multicall and Multicall2

Usage Example

Here's a basic example of how to use MultiCall v3 to batch multiple contract reads:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
 
interface IMulticall3 {
    struct Call3 {
        address target;
        bool allowFailure;
        bytes callData;
    }
    
    struct Result {
        bool success;
        bytes returnData;
    }
    
    function aggregate3(Call3[] calldata calls) 
        external payable returns (Result[] memory returnData);
}
 
contract MulticallExample {
    IMulticall3 constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);
    
    function batchTokenBalances(
        address[] calldata tokens,
        address account
    ) external view returns (uint256[] memory balances) {
        IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](tokens.length);
        
        // Prepare batch calls
        for (uint i = 0; i < tokens.length; i++) {
            calls[i] = IMulticall3.Call3({
                target: tokens[i],
                allowFailure: true,
                callData: abi.encodeWithSignature("balanceOf(address)", account)
            });
        }
        
        // Execute batch
        IMulticall3.Result[] memory results = multicall.aggregate3(calls);
        balances = new uint256[](results.length);
        
        // Parse results
        for (uint i = 0; i < results.length; i++) {
            if (results[i].success) {
                balances[i] = abi.decode(results[i].returnData, (uint256));
            }
        }
    }
}

Security Considerations

⚠️ Important Security Notes:

  • Never leave funds in the contract - Any ETH or tokens held by MultiCall3 can be stolen by anyone
  • Don't approve token spending - Never approve MultiCall3 to spend your tokens
  • Understand call behavior - Be aware of CALL vs DELEGATECALL implications
  • This contract is unaudited - Use with appropriate caution

Available Methods

  • aggregate3(Call3[] calls) - Batch calls with individual failure handling
  • aggregate3Value(Call3Value[] calls) - Batch calls with ETH value transfers
  • blockAndAggregate(Call3[] calls) - Batch calls with block information
  • getBasefee() - Get current base fee
  • getBlockHash(uint256 blockNumber) - Get block hash
  • getCurrentBlockDifficulty() - Get block difficulty
  • getEthBalance(address addr) - Get ETH balance

For complete documentation and deployment addresses across all supported chains, visit multicall3.com.

On this page