Add Multicall module#2608
Conversation
Amxx
left a comment
There was a problem hiding this comment.
Code looks good to me.
You could shorten it even more by doing :
results[i] = Address.functionDelegateCall(address(this), data[i]);
Depending on how solidity does optimization, that might even save a memory copy.
Next we'll need tests and documentation
|
For the record: https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/base/Multicall.sol |
|
Doing some quick tests: // SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.0;
pragma abicoder v2;
import "./ERC20Mock.sol";
/// @title Multicall
/// @notice Enables calling multiple methods in a single call to the contract
abstract contract Multicall {
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
(bool success, bytes memory result) = address(this).delegatecall(data[i]);
if (!success) {
// Next 5 lines from https://ethereum.stackexchange.com/a/83577
if (result.length < 68) revert();
assembly {
result := add(result, 0x04)
}
revert(abi.decode(result, (string)));
}
results[i] = result;
}
}
}
contract UniswapMultiCallTokenMock is ERC20Mock, Multicall {
constructor (uint256 initialBalance) ERC20Mock("BatchCallToken", "BCT", msg.sender, initialBalance) {}
}v.s. // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/BatchCall.sol";
import "./ERC20Mock.sol";
contract BatchCallTokenMock is ERC20Mock, BatchCall {
constructor (uint256 initialBalance) ERC20Mock("BatchCallToken", "BCT", msg.sender, initialBalance) {}
}results in |
This shows that, without optimisation, uniswap multicall is more expensive to deploy by about 20k gas, but less expensive to use.. doing |
|
Should I switch to their implementation? |
|
The additional cost is probably that we are calling |
frangio
left a comment
There was a problem hiding this comment.
Other than my suggestions for testing this looks good.
Amxx
left a comment
There was a problem hiding this comment.
All this looks good to me, I'd personally go with uniswap implementation if that can save some gas, or do a manual try-catch block ... but that is not a strong opinion.
|
Linking @Amxx's |
Fixes #2558