16

GitHub - willzhuang/multicall: Multicall: Aggregate multiple constant function c...

 1 year ago
source link: https://github.com/willzhuang/multicall
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Multicall •

Multicall aggregates results from multiple contract constant function calls.

This reduces the number of separate JSON RPC requests that need to be sent (especially useful if using remote nodes like Infura), while also providing the guarantee that all values returned are from the same block (like an atomic read) and returning the block number the values are from (giving them important context so that results from old blocks can be ignored if they're from an out-of-date node).

There are three contracts in this repository:

  • Multicall: The original contract containing an aggregate method to batch calls
  • Multicall2: The same as Multicall, but provides additional functions that allow calls within the batch to fail. Useful for situations where a call may fail depending on the state of the contract.
  • Multicall3: This is the recommended version. It's ABI is backwards compatible with Multicall and Multicall2, but it's cheaper to use (so you can fit more calls into a single request), and it adds an aggregate3 method so you can specify whether calls are allowed to fail on a per-call basis. Additionally, it's deployed on every network at the same address.

These contracts can also be used to batch on-chain transactions. If using them for this purpose, be aware these contracts are unaudited so use them at your own risk. Additionally, make sure you understand how msg.sender works when calling vs. delegatecalling to the Multicall contract, as well as the risks of using msg.value in a multicall. To learn more about the latter, see here and here.

You can obtain the ABI for the Multicall contracts in the following ways:

  • Download the ABI from the releases page
  • Copy the ABI from Etherscan
  • Install Foundry and run cast interface 0xcA11bde05977b3631167028862bE2a173976CA11
  • Copy the human-readable ABI below for use with ethers.js.

Deployments

Multicall3 Contract Addresses

Multicall3 contains the following improvements over prior multicall contracts:

  • Cheaper to use: fit more calls into a single request before hitting the RPC's eth_call gas limit.
  • Backwards compatible: it can be dropped in to existing code by simply changing the address.
  • Uses the same, memorable deployment address on the 50+ networks it's deployed to.
Chain Chain ID Address
Mainnet 1 0xcA11bde05977b3631167028862bE2a173976CA11
Kovan 42 0xcA11bde05977b3631167028862bE2a173976CA11
Rinkeby 4 0xcA11bde05977b3631167028862bE2a173976CA11
Görli 5 0xcA11bde05977b3631167028862bE2a173976CA11
Ropsten 3 0xcA11bde05977b3631167028862bE2a173976CA11
Sepolia 11155111 0xcA11bde05977b3631167028862bE2a173976CA11
Optimism 10 0xcA11bde05977b3631167028862bE2a173976CA11
Optimism Kovan 69 0xcA11bde05977b3631167028862bE2a173976CA11
Optimism Görli 420 0xcA11bde05977b3631167028862bE2a173976CA11
Arbitrum 42161 0xcA11bde05977b3631167028862bE2a173976CA11
Arbitrum Nova 42170 0xcA11bde05977b3631167028862bE2a173976CA11
Arbitrum Görli 421613 0xcA11bde05977b3631167028862bE2a173976CA11
Arbitrum Rinkeby 421611 0xcA11bde05977b3631167028862bE2a173976CA11
Polygon 137 0xcA11bde05977b3631167028862bE2a173976CA11
Mumbai 80001 0xcA11bde05977b3631167028862bE2a173976CA11
Polygon zkEVM 1101 0xcA11bde05977b3631167028862bE2a173976CA11
Polygon zkEVM Testnet 1442 0xcA11bde05977b3631167028862bE2a173976CA11
Gnosis Chain (xDai) 100 0xcA11bde05977b3631167028862bE2a173976CA11
Avalanche 43114 0xcA11bde05977b3631167028862bE2a173976CA11
Avalanche Fuji 43113 0xcA11bde05977b3631167028862bE2a173976CA11
Fantom Testnet 4002 0xcA11bde05977b3631167028862bE2a173976CA11
Fantom Opera 250 0xcA11bde05977b3631167028862bE2a173976CA11
BNB Smart Chain 56 0xcA11bde05977b3631167028862bE2a173976CA11
BNB Smart Chain Testnet 97 0xcA11bde05977b3631167028862bE2a173976CA11
Moonbeam 1284 0xcA11bde05977b3631167028862bE2a173976CA11
Moonriver 1285 0xcA11bde05977b3631167028862bE2a173976CA11
Moonbase Alpha Testnet 1287 0xcA11bde05977b3631167028862bE2a173976CA11
Harmony 1666600000 0xcA11bde05977b3631167028862bE2a173976CA11
Cronos 25 0xcA11bde05977b3631167028862bE2a173976CA11
Fuse 122 0xcA11bde05977b3631167028862bE2a173976CA11
Flare Mainnet 14 0xcA11bde05977b3631167028862bE2a173976CA11
Songbird Canary Network 19 0xcA11bde05977b3631167028862bE2a173976CA11
Coston Testnet 16 0xcA11bde05977b3631167028862bE2a173976CA11
Coston2 Testnet 114 0xcA11bde05977b3631167028862bE2a173976CA11
Boba 288 0xcA11bde05977b3631167028862bE2a173976CA11
Aurora 1313161554 0xcA11bde05977b3631167028862bE2a173976CA11
Astar 592 0xcA11bde05977b3631167028862bE2a173976CA11
OKC 66 0xcA11bde05977b3631167028862bE2a173976CA11
Heco Chain 128 0xcA11bde05977b3631167028862bE2a173976CA11
Metis 1088 0xcA11bde05977b3631167028862bE2a173976CA11
RSK 30 0xcA11bde05977b3631167028862bE2a173976CA11
RSK Testnet 31 0xcA11bde05977b3631167028862bE2a173976CA11
Evmos 9001 0xcA11bde05977b3631167028862bE2a173976CA11
Evmos Testnet 9000 0xcA11bde05977b3631167028862bE2a173976CA11
Thundercore 108 0xcA11bde05977b3631167028862bE2a173976CA11
Thundercore Testnet 18 0xcA11bde05977b3631167028862bE2a173976CA11
Oasis 42262 0xcA11bde05977b3631167028862bE2a173976CA11
Celo 42220 0xcA11bde05977b3631167028862bE2a173976CA11
Celo Alfajores Testnet 44787 0xcA11bde05977b3631167028862bE2a173976CA11
Godwoken 71402 0xcA11bde05977b3631167028862bE2a173976CA11
Godwoken Testnet 71401 0xcA11bde05977b3631167028862bE2a173976CA11
Klaytn 8217 0xcA11bde05977b3631167028862bE2a173976CA11
Milkomeda 2001 0xcA11bde05977b3631167028862bE2a173976CA11
KCC 321 0xcA11bde05977b3631167028862bE2a173976CA11
Velas 106 0xcA11bde05977b3631167028862bE2a173976CA11
Telos 40 0xcA11bde05977b3631167028862bE2a173976CA11
Step Network 1234 0xcA11bde05977b3631167028862bE2a173976CA11
Canto 7700 0xcA11bde05977b3631167028862bE2a173976CA11
Iotex 4689 0xcA11bde05977b3631167028862bE2a173976CA11
Bitgert 32520 0xcA11bde05977b3631167028862bE2a173976CA11
Kava 2222 0xcA11bde05977b3631167028862bE2a173976CA11
Mantle Testnet 5001 0xcA11bde05977b3631167028862bE2a173976CA11
Shardeum Sphinx 8082 0xcA11bde05977b3631167028862bE2a173976CA11
Base Testnet 84531 0xcA11bde05977b3631167028862bE2a173976CA11
DFK Chain Test 335 0xcA11bde05977b3631167028862bE2a173976CA11
DFK Chain 53935 0xcA11bde05977b3631167028862bE2a173976CA11
Neon EVM DevNet 245022926 0xcA11bde05977b3631167028862bE2a173976CA11
Linea Goerli Testnet 59140 0xcA11bde05977b3631167028862bE2a173976CA11

If there is a network Multicall3 is not yet deployed on, please open an issue with a link to the block explorer. You can speed up the new deploy by sending funds to cover the deploy cost to the deployer account: 0x05f32B3cC3888453ff71B01135B34FF8e41263F2

Historical Deployments

Multicall3 is the recommended version for most use cases, but deployment addresses for Multicall and Multicall2 are retained below for posterity. The Multicall smart contract was originally intended to be used with Multicall.js in front-end dapps. However, that library has not been updated to work with Multicall2 and Multicall3, so it will likely only work for the original Multicall contract.

Multicall Contract Addresses

The deployed Multicall contract can be found in commit bb309a9 or earlier. After that commit, the contract was updated to a more recent Solidity version (with minimal improvements), primarily for compatibility with the test suite.

Multicall2 Contract Addresses

The deployed Multicall2 contract can be found in commit bb309a9 or earlier. After that commit, the contract was updated to a more recent Solidity version (with minimal improvements), primarily for compatibility with the test suite.

Multicall2 is the same as Multicall, but provides additional functions that allow calls within the batch to fail. Useful for situations where a call may fail depending on the state of the contract.

Third-Party Deployments

The following addresses have been submitted by external contributors and have not been vetted by Multicall maintainers.

Development

This repo uses Foundry for development and testing and git submodules for dependency management.

Clone the repo and run forge install to install dependencies and forge test to run tests.

Foundry Setup

If you don't have Foundry installed, run the command below to get foundryup, the Foundry toolchain installer:

curl -L https://foundry.paradigm.xyz | bash

Then, in a new terminal session or after reloading your PATH, run foundryup to get the latest forge and cast binaries.

To learn more about Foundry:

Gas Golfing Tricks and Optimizations

Below is a list of some of the optimizations used by Multicall3's aggregate3 and aggregate3Value methods:

  • In for loops, array length is cached to avoid reading the length on each loop iteration
  • In for loops, the counter is incremented within an unchecked block
  • In for loops, the counter is incremented with the prefix increment (++i) instead of a postfix increment (i++)
  • All revert strings fit within a single 32 byte slot
  • Function parameters use calldata instead of memory
  • Instead of requiring call.allowFailure || result.success, we use assembly's or() instruction to avoid a JUMPI and iszero() since it's cheaper to evaluate both conditions
  • Methods are given a payable modifier which removes a check that msg.value == 0 when calling a method
  • Calldata and memory pointers are used to cache values so they are not read multiple times within a loop
  • No block data (e.g. block number, hash, or timestamp) is returned by default, and is instead left up to the caller
  • The value accumulator in aggregate3Value is within an unchecked block

Read more about Solidity gas optimization tips:

Human-Readable ABI

Below is the human-readable ABI. This can be directly passed into an ethers.js Contract or Interface constructor.

const MULTICALL_ABI = [
  // https://github.com/mds1/multicall
  'function aggregate(tuple(address target, bytes callData)[] calls) payable returns (uint256 blockNumber, bytes[] returnData)',
  'function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)',
  'function aggregate3Value(tuple(address target, bool allowFailure, uint256 value, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)',
  'function blockAndAggregate(tuple(address target, bytes callData)[] calls) payable returns (uint256 blockNumber, bytes32 blockHash, tuple(bool success, bytes returnData)[] returnData)',
  'function getBasefee() view returns (uint256 basefee)',
  'function getBlockHash(uint256 blockNumber) view returns (bytes32 blockHash)',
  'function getBlockNumber() view returns (uint256 blockNumber)',
  'function getChainId() view returns (uint256 chainid)',
  'function getCurrentBlockCoinbase() view returns (address coinbase)',
  'function getCurrentBlockDifficulty() view returns (uint256 difficulty)',
  'function getCurrentBlockGasLimit() view returns (uint256 gaslimit)',
  'function getCurrentBlockTimestamp() view returns (uint256 timestamp)',
  'function getEthBalance(address addr) view returns (uint256 balance)',
  'function getLastBlockHash() view returns (bytes32 blockHash)',
  'function tryAggregate(bool requireSuccess, tuple(address target, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)',
  'function tryBlockAndAggregate(bool requireSuccess, tuple(address target, bytes callData)[] calls) payable returns (uint256 blockNumber, bytes32 blockHash, tuple(bool success, bytes returnData)[] returnData)',
];

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK