AlertSourceDiscuss
Skip to content
On this page

ERC-6357: Single-contract Multi-delegatecall

Allows an EOA to call multiple functions of a smart contract in a single transaction

⚠️ DraftERC

Draft Notice

This EIP is in the process of being drafted. The content of this EIP is not final and can change at any time; this EIP is not yet suitable for use in production. Thank you!

AuthorsGavin John (@Pandapip1)
Created2023-01-18

Abstract

This EIP standardizes an interface containing a single function, multicall, allowing EOAs to call multiple functions of a smart contract in a single transaction, and revert all calls if any call fails.

Motivation

Currently, in order to transfer several ERC-721 NFTs, one needs to submit a number of transactions equal to the number of NFTs being tranferred. This wastes users' funds by requiring them to pay 21000 gas fee for every NFT they transfer.

Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Contracts implementing this EIP must implement the following interface:

solidity
pragma solidity ^0.8.0;

interface IMulticall {
    /// @notice           Takes an array of abi-encoded call data, delegatecalls itself with each calldata, and returns the abi-encoded result
    /// @dev              Reverts if any delegatecall reverts
    /// @param    data    The abi-encoded data
    /// @returns  results The abi-encoded return values
    function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results);

    /// @notice           OPTIONAL. Takes an array of abi-encoded call data, delegatecalls itself with each calldata, and returns the abi-encoded result
    /// @dev              Reverts if any delegatecall reverts
    /// @param    data    The abi-encoded data
    /// @param    values  The effective msg.values. These must add up to at most msg.value
    /// @returns  results The abi-encoded return values
    function multicallPayable(bytes[] calldata data, uint256[] values) external payable virtual returns (bytes[] memory results);
}

Rationale

Needs discussion.

Backwards Compatibility

This is compatible with most existing multicall functions.

Reference Implementation

solidity
pragma solidity ^0.8.0;

/// Derived from OpenZeppelin's implementation
abstract contract Multicall is IMulticall {
    function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            (bool success, bytes memory returndata) = address(this).delegatecall(data);
            require(success);
            results[i] = returndata;
        }
        return results;
    }
}

Security Considerations

Needs discussion.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Gavin John, "ERC-6357: Single-contract Multi-delegatecall[DRAFT]," Ethereum Improvement Proposals, no. 6357, 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6357.