I want to understand, what happens under the hoods in this (very unsafe, but educative) example.
contract Actual {
function () external { }
}
interface Expected {
function g() external returns (uint256);
}
contract MyContract {
function g(address a) public returns (uint256 x) {
// fails at run-time
x = Expected(a).g();
}
}
Let us suppose I have create an instance of MyContract i_MC
and an Instance of Actual i_A
. Now I call function i_MC.g()
with i_A
's address as input. The call results in a revert.
The high-level explanation is very simple: i_MC
expect to call the g()
function of an instance of type Expected, but it actually invoked the fallback function of i_A
, which does not return anything.
Is that the case, because the caller is looking for an unallocated portion of memory (after the \mu_i
in the yellow paper), because the fallback function did not execute the RETURN
opcode, which also expands the memory?