Omniscia AllianceBlock Audit

Multicall2 Manual Review Findings

Multicall2 Manual Review Findings

M2L-01M: Discrepant Documentation of Code

Description:

The Multicall2 contract documentation specifies that it is meant to aggregate results from multiple read-only function calls, however, the contract is capable of performing state-mutating calls.

Impact:

The severity of this exhibit cannot be assessed as the true purpose of the Multicall2 contract cannot be deduced via its code.

Example:

contracts/Multicall2.sol
3/// @title Multicall2 - Aggregate results from multiple read-only function calls
4/// @author Michael Elliot <mike@makerdao.com>
5/// @author Joshua Levine <joshua@makerdao.com>
6/// @author Nick Johnson <arachnid@notdot.net>
7
8contract Multicall2 {
9 struct Call {
10 address target;
11 bytes callData;
12 }
13 struct Result {
14 bool success;
15 bytes returnData;
16 }
17
18 function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
19 blockNumber = block.number;
20 returnData = new bytes[](calls.length);
21 for (uint256 i = 0; i < calls.length; i++) {
22 (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
23 require(success, "Multicall aggregate: call failed");
24 returnData[i] = ret;
25 }
26 }

Recommendation:

We advise the code to either be updated as read-only (i.e. introducing view to the relevant functions and performing staticcall operations), or its documentation to be updated based on the desires of the AllianceBlock team.

Alleviation (54fd570de2):

The Multicall2::aggregate function was updated to perform a staticcall, however, the Multicall2::tryAggregate still performs a call operation rendering this exhibit partially alleviated.

Alleviation (d7618eed4e):

The Multicall2::tryAggregate function was updated to perform a staticcall as well which was accompanied by mutability changes in the upper-level function definitions to view.

As such, we consider this exhibit fully alleviated.