book icon indicating copy to clipboard operation
book copied to clipboard

Explain why the examples for `mockCall` work

Open PaulRBerg opened this issue 3 years ago • 2 comments

The reference for the mockCall cheatcode makes this statement:

Calls to mocked addresses may revert if there is no code on the address. This is because Solidity inserts an extcodesize check before some contract calls.

Then it provides the following code snippet as an example:

function testMockCall() public {
    vm.mockCall(
        address(0),
        abi.encodeWithSelector(MyToken.balanceOf.selector, address(1)),
        abi.encode(10)
    );
    assertEq(IERC20(address(0)).balanceOf(address(1)), 10);
}

Running this code myself, I can see that it works. But why? As far as I can tell, there is no code pre-loaded at the zero address. is it that by default, the EVM used by Forge loads some dummy code at the zero address?

I think that it should be clarified why the code snippets work.

PaulRBerg avatar May 03 '22 12:05 PaulRBerg

Because the function call returns a value, so Solidity does not insert the extcodesize check, since it can just check if any value was returned. The reason I didn't explain that in the cheatcode reference is because I'm not sure it's true for all Solidity versions (it's an optimization), and I'm not sure it will always be true.

We can still add it though, but I'd at least like to be able to clarify what versions this is true of - and if its even true with the optimizer disabled.

onbjerg avatar May 03 '22 14:05 onbjerg

Should we then reword the first statement to something like this?

Calls to mocked addresses may revert if there is no code on the address. This is because in some versions of Solidity, the compiler inserts an extcodesize check before some contract calls.

This is still vague but a bit more explicit than the previous wording.

PaulRBerg avatar May 03 '22 17:05 PaulRBerg