Hi there, as the title implies, OZ is using a delegatecall in a multicall and MakerDao is using a normal call. I’m wondering what the logics behind this difference are.
These two contracts are completely different. The shared contract name is confusing but fortunately the function names are different.
Notice that MakerDao’s aggregate will call each function on a different target contract. Since it uses call, msg.sender will be the Multicall contract itself.
OpenZeppelin’s multicall, on the other hand, performs delegatecall to this. Since it uses delegatecall, msg.sender remains the same account that invoked multicall in the first place.
OpenZeppelin’s is a module that a developer can include in their own contract to allow users to batch multiple function calls to it in one transaction. Since msg.sender is preserved, it’s equivalent to sending multiple transactions from an EOA (non-contract account).
MakerDao’s is a helper contract that a developer can deploy in order to use as a sort of forwarding proxy that will aggregate the result of multiple calls. Since msg.sender is not preserved, its use is more limited, but many circumstances may still find it useful.
Right. By saying more generic, I was referring to the fact that the array calls can include different tareget addresses which can of course be all the same. That is then reducing the function to a multicall to a single address with multiple calldata.
But it is alright. This is enough to see the differences clearly. Thanks, @frangio .
Ah I see why you’d say it’s more generic. But the thing is that delegatecall and call do very very different things, so it’s not possible to say that one is more generic than the other.
Okay I see what you mean about making a more generic multicall with delegatecall. But this is not a good idea. delegatecall gives the target contract arbitrary access to storage. It’s safe to delegate to this, but generally unsafe to delegate to an arbitrary contract.
Try searching online to better understand how it works and why it’s unsafe. Quick one I found:
Sorry to revive this, but i was wondering if it's safe to create a new separate contract similar to makerdao's multicall, but using delegateCall instead.
W.R.T the security risk of contract storage being accessed, we can check the msg.sender to be EOA,
my bad, i had the impression that delegatecall mimics a call function while preserving msg.sender and msg.value.
but looks like it works more like a cross contract modifier where the function of an external contract is copied to address(this) and executed on address(this). state of calling contract can be changed but state of external contract cannot be changed