Coder Social home page Coder Social logo

mds1 / multicall Goto Github PK

View Code? Open in Web Editor NEW

This project forked from makerdao/multicall

889.0 6.0 146.0 417 KB

Multicall: Aggregate multiple constant function call results into one

Home Page: https://multicall3.com

License: MIT License

Solidity 100.00%

multicall's Introduction

Multicall3

tests coverage license

Multicall3 is deployed on over 70+ chains at 0xcA11bde05977b3631167028862bE2a173976CA11. The full list of deployed chains along with the Multicall3 ABI can be found at https://multicall3.com. The ABI is provided in various formats, and can be copied to your clipboard or downloaded to a file.

Multicall3 is the primary contract in this repository, and is recommended for all use cases1.

Usage

Multicall3 has two main use cases:

  • Aggregate results from multiple contract reads into a single JSON-RPC request.
  • Execute multiple state-changing calls in a single transaction.

Because it can be used for both use cases, no methods in this contract are view, and all can mutate state and are payable.

Batch Contract Reads

This is the most common use case for executing a multicall. This allows a single eth_call JSON RPC request to return the results of multiple contract function calls. This has many benefits, because it:

  • Reduces the number of separate JSON RPC requests that need to be sent, which is especially useful if using remote nodes like Infura. This (1) reduces RPC usage and therefore costs, and (2) reduces the number of round trips between the client and the node, which can significantly improve performance.
  • Guarantees that all values returned are from the same block.
  • Enables block number or timestamp to be returned with the read data, to help detect stale data.

Many libraries and tools such as ethers-rs, viem, and ape have native Multicall3 integration. To learn how to use Multicall3 with these tools, check out this repo's examples and read the documentation for the tool you're using to learn more.

When directly interacting with the contract to batch calls, the aggregate3 method is likely what you'll want to use. It takes an array of Call3 structs, and returns an array of Result structs:

struct Call3 {
    // Target contract to call.
    address target;
    // If false, the entire call will revert if the call fails.
    bool allowFailure;
    // Data to call on the target contract.
    bytes callData;
}

struct Result {
    // True if the call succeeded, false otherwise.
    bool success;
    // Return data if the call succeeded, or revert data if the call reverted.
    bytes returnData;
}

/// @notice Aggregate calls, ensuring each returns success if required
/// @param calls An array of Call3 structs
/// @return returnData An array of Result structs
function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData);

To obtain the block number or timestamp of the block the calls were executed in with your return data, simply add a call where the target is the Multicall3 contract itself, and the callData is the getBlockNumber or getCurrentBlockTimestamp method.

There are a number of other methods to return block properties, including:

If you need to send less calldata as part of your multicall and can tolerate less granularity of specifying which calls fail, you can check out the other aggregation methods:

  • aggregate3Value: Similar to aggregate3, but also lets you send values with calls.
  • aggregate: Returns a tuple of (uint256 blockNumber, bytes[] returnData) and reverts if any call fails.
  • blockAndAggregate: Similar to aggregate, but also returns the block number and block hash.
  • tryAggregate: Takes a bool value indicating whether success is required for all calls, and returns a tuple of (bool success, bytes[] returnData)[].
  • tryBlockAndAggregate: Similar to tryAggregate, but also returns the block number and block hash.

Note that the above tuples are represented as structs in the code, but are shown above as tuples for brevity.

Batch Contract Writes

If using Multicall3 for this purpose, be aware it is unaudited, so use at your own risk. However, because it is a stateless contract, it should be safe when used correctly—it should never hold your funds after a transaction ends, and you should never approve Multicall3 to spend your tokens.

Multicall3 can also be used to batch on-chain transactions using the methods described in the Batch Contract Reads section.

When using Multicall3 for this purpose, there are two important details you MUST understand.

  1. How msg.sender behaves when calling vs. delegatecalling to a contract.
  2. The risks of using msg.value in a multicall.

Before explaining both of these, let's first cover some background on how the Ethereum Virtual Machine (EVM) works.

There are two types of accounts in Ethereum: Externally Owned Accounts (EOAs) and Contract Accounts. EOAs are controlled by private keys, and Contract Accounts are controlled by code.

When an EOA calls a contract, the msg.sender value during execution of the call provides the address of that EOA. This is also true if the call was executed by a contract. The word "call" here specifically refers to the CALL opcode. Whenever a CALL is executed, the context changes. New context means storage operations will be performed on the called contract, there is a new value (i.e. msg.value), and a new caller (i.e. msg.sender).

The EVM also supports the DELEGATECALL opcode, which is similar to CALL, but different in a very important way: it does not change the context of the call. This means the contract being delegatecalled will see the same msg.sender, the same msg.value, and operate on the same storage as the calling contract. This is very powerful, but can also be dangerous.

It's important to note that you cannot delegatecall from an EOA—an EOA can only call a contract, not delegatecall it.

Now that we understand the difference between CALL and DELEGATECALL, let's see how this applies to msg.sender and msg.value concerns. We know that we can either CALL or DELEGATECALL to a contract, and that msg.sender will be different depending on which opcode we use.

Because you cannot delegatecall from an EOA, this significantly reduces the benefit of calling Multicall3 from an EOA—any calls the Multicall3 executes will have the MultiCall3 address as the msg.sender. This means you should only call Multicall3 from an EOA if the msg.sender does not matter.

If you are using a contract wallet or executing a call to Multicall3 from another contract, you can either CALL or DELEGATECALL. Calls will behave the same as described above for the EOA case, and delegatecalls will preserve the context. This means if you delegatecall to Multicall3 from a contract, the msg.sender of the calls executed by Multicall3 will be that contract. This can be very useful, and is how the Gnosis Safe Transaction Builder works to batch calls from a Safe.

Similarly, because msg.value does not change with a delegatecall, you must be careful relying on msg.value within a multicall. To learn more about this, see here and here.

Deployments and ABI

Existing Deployments

Multicall3 is deployed on over 100 chains at 0xcA11bde05977b3631167028862bE2a173976CA112. A sortable, searchable list of all chains it's deployed on can be found at https://multicall3.com/deployments.

The ABI can be found on https://multicall3.com/abi, where it can be downloaded or copied to the clipboard in various formats, including:

  • Solidity interface.
  • JSON ABI, prettified.
  • JSON ABI, minified.
  • ethers.js human readable ABI.
  • viem human readable ABI.

Alternatively, you can:

  • Download the ABI from the releases page.
  • Copy the ABI from Etherscan.
  • Install Foundry and run cast interface 0xcA11bde05977b3631167028862bE2a173976CA11.

New Deployments

There are two ways to get Multicall3 deployed to a chain:

  1. Deploy it yourself using a pre-signed transaction. Details on how to do this are in the below paragraph.
  2. Request deployment by opening an issue. You can significantly reduce the time to deployment by sending funds to cover the deploy cost to the deployer preparation account: 0x1E91557322053858cf75cFE5b2d030D27cb2cA8D. This account is not the deployer, but is used to hold funds until deployment time. This reduces the risk of using the funds in the deployer account for other purposes to prevent accidentally burning the nonce.

Warning

Before using the signed transaction, you MUST make sure the chain's gas metering is equivalent to the EVM's.

The pre-signed transaction has a gas limit of 1,000,000 gas, so if the chain will require more than 1M gas to deploy the transaction will revert and we will be unable to deploy Multicall3 at that address. If that happens, the only way to get Multicall3 at the expected address is for the chain to place the contract there as a predeploy.

If you are unsure how to verify this, you can either use the eth_estimateGas RPC method or simply deploy the Multicall3 contract from another account and see how much gas deployment used. EVM chains should require exactly 872,776 gas to deploy Multicall3.

Arbitrum chains are well-known chains that cannot be deployed using the pre-signed transaction. See this deployment on Arbitrum One that required a gas limit of 14,345,935 gas—well above the 1,000,000 gas limit of the signed transaction.

It's recommended to test sending the transaction on a local network——such as an anvil instance forked from the chain—to verify it works as expected before deploying to a production network. You can see an example of a successful deployment using the signed transaction on Base here.

After deploying, please open a PR to update the deployments.json file with the new deployment, this way other users can easily know that it's deployed.

Below is the signed transaction. It has a gas limit of 1,000,000 gas and a gas price of 100 gwei, so before deploying you'll need to send at least 0.1 ETH to the deployer preparation address (0x1E91557322053858cf75cFE5b2d030D27cb2cA8D). This account is not the deployer, but is used to hold funds until deployment time. This reduces the risk of using the funds in the deployer account for other purposes to prevent accidentally burning the nonce.

0xf90f538085174876e800830f42408080b90f00608060405234801561001057600080fd5b50610ee0806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c00331ca0edce47092c0f398cebf3ffc267f05c8e7076e3b89445e0fe50f6332273d4569ba01b0b9d000e19b24c5869b0fc3b22b0d6fa47cd63316875cbbd577d76e6fde086

To deploy with cast:

# `TX` is the signed transaction above.
# `RPC_URL` is the RPC URL of the chain you want to deploy to.
cast publish $TX --rpc-url $RPC_URL

Contract Verification

To verify the code on a block explorer, use the following parameters:

  • Paste in the code from Multicall3.sol
  • Select solidity 0.8.12
  • Optimizer enabled with 10000000 runs
  • No constructor arguments

Security

This contract is unaudited.

For on-chain transactions using Multicall3, or for contracts inheriting from Multicall3:

  • Ensure it NEVER holds funds after a transaction ends. Any ETH, tokens, or other funds held by this contract can be stolen. There are bots that monitor for this and they will immediately steal any funds they find.
  • Never approve Multicall3 to spend your tokens. If you do, anyone can steal your tokens. There are likely bots that monitor for this as well. - It is not recommended to inherit from this contract if your contract will hold funds. But if you must, be sure you know what you're doing and protect all state changing methods with an onlyOwner modifier or similar so funds cannot be stolen.
  • Be sure you understand CALL vs. DELEGATECALL behavior depending on your use case. See the Batch Contract Writes section for more details.

For off-chain reads the worst case scenario is you get back incorrect data, but this should not occur for properly formatted calls.

Development

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

Clone the repo and run forge test to run tests. Forge will automatically install any missing dependencies.

The repo for https://multicall3.com can be found here.

Gas Golfing Tricks and Optimizations

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

  • 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:

Footnotes

  1. Multicall is the original contract, and Multicall2 added support for handling failed calls in a multicall. Multicall3 is recommended over these because it's backwards-compatible with both, cheaper to use, adds new methods, and is deployed on more chains. You can read more about the original contracts and their deployments in the makerdao/multicall repo.

  2. There are a few unofficial deployments at other addresses for chains that compute addresses differently, which can also be found at

  3. Some of these tricks are outdated with newer Solidity versions and via-ir. Be sure to benchmark your code before assuming the changes are guaranteed to reduce gas usage.

multicall's People

Contributors

007vasy avatar 0xbeny avatar 0xsylice avatar codespool avatar dbadoy avatar ethanbennett avatar fanbsb avatar fsjuhl avatar gbalabasquer avatar hoale58-vl avatar jparklev avatar kristiantokarim avatar mds1 avatar michaelelliot avatar mowl-glyph avatar nullbitx8 avatar oxsaturn avatar paulrberg avatar pcaversaccio avatar pengdeng-cyber avatar phearnot avatar pierreossun avatar refcell avatar rkalis avatar shankarwarang avatar skenaja avatar thegreataxios avatar willpote avatar xalexec avatar xteriotech avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

multicall's Issues

Deploy to Optimism Göerli

Hi, awesome contract!

From Optimism docs:

Deprecation notice
We are transitioning our test network to Goerli. We expect Optimistic Kovan to exist until August 15th, 2022.

Could you please deploy it to Optimism Göerli? Thank you!

Mantle Testnet

Can you please deploy multicallv3 on mantle testnet

I already sent 50 BIT as funds to 0x05f32B3cC3888453ff71B01135B34FF8e41263F2 address

Restrictive pragma makes it difficult to use this repository

Unless I am misunderstanding how I should this, I think that the current pragma is unnecessarily restrictive by being locked to 0.8.12. I am getting this compiler error in my project, which uses v0.8.17:

Compiler run failed
error[5333]: ParserError: Source file requires different compiler version (current compiler is 0.8.17+commit.8df45f5f.Darwin.appleclang) - note that nightly builds are considered to be strictly less than the released version
 --> lib/multicall/src/Multicall3.sol:2:1:
  |
2 | pragma solidity 0.8.12;
  | ^^^

Is there any specific reason for locking in the pragma to v0.8.12 and not writing it like this?

pragma solidity >=0.8.12 <0.9.0;

It also happens that this is a version that contains an important bug related to abi.encodeCall, which is highly relevant in the context of Multicall.

Examples in the README

Hey Matt, thanks for building this. I just started playing with it today, and it's awesome.

I was wondering if you know of any good example repositories that could be included in the README? I think that it would be helpful to provide some - for instance, a repo that uses multicall to query the token balances of multiple addresses is probably a common use case.

Feat: provide machine readable deployments file

Providing a json file may be useful, as I am using this for an EIP

Perhaps using the chains canonical ChainId as an identifier would be more appropriate (as then you could use get_chainId from the contract to test against the address mapped to the chain_id prefix

e.g.:

[
  {
    "Network": "Address",
    "Mainnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Kovan": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Rinkeby": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Görli": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Ropsten": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Sepolia": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Optimism": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Optimism Kovan": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Arbitrum": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Arbitrum Rinkeby": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Polygon": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Mumbai": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Gnosis Chain (xDai)": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Avalanche": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Avalanche Fuji": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Fantom Testnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Fantom Opera": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "BNB Smart Chain": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "BNB Smart Chain Testnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Moonbeam": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Moonriver": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Moonbase Alpha Testnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Harmony": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Cronos": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Fuse": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Songbird Canary Network": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Coston Testnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Boba": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Aurora": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Astar": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "OKC": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Heco Chain": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Metis": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "RSK": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "RSK Testnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Evmos": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Evmos Testnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Thundercore": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Thundercore Testnet": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Oasis": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "Celo": "0xcA11bde05977b3631167028862bE2a173976CA11"
  }
]

Deployment of MulticallV3 to Boba, Cronos, Aurora, Astar, Metis

Hi there, I'm Jacky from Ape Board!

Ape Board is heavily using Multicall and really love the improvements on MulticallV3!

Do you by any chance have some time to deploy it on Boba, Cronos, Aurora, Astar and Metis?

I saw that the deployment gas used was around 872,776 (rounded up to 900,000),
So I've sent along some deployment costs to 0x05f32B3cC3888453ff71B01135B34FF8e41263F2 on these chains.

Chain Funds sent Transaction
BOBA 0.0009 ETH https://blockexplorer.boba.network/tx/0xc3242...09a696
CRONOS 4.5 CRO https://cronos.org/explorer/tx/0x193fd...72e92b
AURORA 0.000027 ETH https://aurorascan.dev/tx/0x0af59...1ac04e
ASTAR 0.0009 ASTR https://blockscout.com/astar/tx/0xe2d31...cbff25
METIS 0.0072 METIS https://andromeda-explorer.metis.io/tx/0x18149...fdb4e8

Please let me know if the funds are not enough, so I could send more!

Make this an ERC (or have I missed it?)

Multicall is let's say, "Awesome" and solves many problems for all users, it will be ideal if it is more widely known. Have you thought about creating an ERC? Or have I missed it?

Revert reason

Hey @mds1! Is it possible to get the revert reason from the individual calls if any fail? I'm playing around with ethers.js callStatic to pull out the info but the best I can get so far is which call failed, but not why it failed.

Deployment of Multicall3 to additional networks

Hey guys, great work with Multicall3! I am currently integrating the contracts with our DefiYield app, moving from v2 to v3. All is great, however, we are missing a few networks. Those are:

OKC: https://www.oklink.com/en/okc
Klaytn: https://scope.klaytn.com/
Milkomeda: https://explorer-mainnet-cardano-evm.c1.milkomeda.com/
KCC: https://explorer.kcc.io/
AURORA https://aurorascan.dev/

Can you guys please deploy on these networks? We will be happy to send funds to cover the deployment cost.

Query: why are all aggregate functions `payable`?

Hi,

I'm new to multicall functions, and trying to use it with my own project in Next.js & ethers.js.

With stateMutability as payable, I got a transaction object as result of calling aggregate functions.
If I want to get the results data, they only way I found is to modify the aggregate function's stateMutability to view in the ABI file.

May I know why these functions are set as payable in the first place?
I guess users wants the results data more?

OR, did I use it the wrong way?
If so, what is the correct way for calling aggregate functions with stateMutability as payable?

Thanks in advance.

Deployment of MulticallV3 to Fuse Network

https://fuse.io is a low-cost EVM chain that we at Beefy Finance have contracts deployed on, and would like to take advantage of the static address.

I've funded the 0x05f32B3cC3888453ff71B01135B34FF8e41263F2 address with 1 FUSE, which should be more than enough to deploy the MulticallV3 contract. Chain ID 122

Thank you!

`estimateGas` using `gasleft()`

Would it be possible to add another utility function equivalent to do multiple eth_estimateGas with some gasleft() magic ✨

Guess its too hard to get it right

feature request - get code multi

Hi, thank you for the development of multicall3, it is very useful.

I have a request for a feature that can further reduce node calls. Rather than hitting the eth rpc method eth_getCode, we can instead implement a getCodeMulti method, something like the below:

    struct ReturnCode {
         address addr;
         bytes code;
     } 

    function getCodeMulti(address[] calldata addresses) public payable returns (ReturnCode[] memory returnContracts) {
         uint256 length = addresses.length;
         returnContracts = new ReturnCode[](length);
         address addr;
         for (uint256 i=0; i < length;) {
             addr = addresses[i];
             returnContracts[i] = ReturnCode(addr, addr.code);
             unchecked {++ i;}
         }
     }

This function would allow for users to get bytecode from multiple contract addresses with only one rpc call. This may be out of scope for this project as it would require redeployment accross all networks, but happy to open a PR or contribute where I can if this feature seems like something worth adding.

Disclose possible attack vector with 'Payable' Multicall usage

I am working on setting up a way of receiving security advisories for contracts / protocol exploits through our DeFi Threat Matrix repo. Part of this was creating an example advisory through GitHub's security options.

In doing some preliminary research for finding a potential security issue with contracts, I came across this issue raised originally in the Uniswap V3 repo concerning the usage of msg.value with having payable

This is present when Multicall is used on any contract which reads the value of msg.value. Multicall is a pattern to call several contract endpoints in one transaction, using delegatecall. A contract endpoint may implicitly assume that it is called in a single transaction, by looking at msg.value. Since the value is defined per transaction, calling the same endpoint twice in one multicall means that the same msg.value may be read several times, even though the value was only transferred once.

Adding additional documentation concerning this issue is my suggestion, I looked at the contract's and did not find any disclaimer, I do not know how you would like to document it, etc. Perhaps a @custom:natspec like :disclaimer or :advisory, all up to you.

The draft reference advisory can be found below:

GHSA-hf8w-qgj8-v7h3

cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.