Solidity reverts when calling a non-existent pure/view function
My colleague and I were tracking down some issues, and we were confused by EVM’s behaviour as it reverts when calling a non-existent pure/view function. We believed that it should hit the fallback function instead of reverting – and thus we started our investigation.
First things first, the conclusion:
- A function call reverts when the function is declared as view or pure in the caller contract but the real implementation changes storage. This is because evm differentiates between state changing and non state changing calls.
- During the compilation, solc would interpret the calls to view or pure function to the opCode
STATICCALL
to specify that it is not state changing. Otherwise it will use the opCodeCALL
. - Even with no state changing statements, the fallback function seems to be considered as state changing.
The scenario we encountered is as follows:
- There are 3 contracts, let’s say:
Caller
,IntendedTarget
,WrongImplementation
. - The Caller contract tries to call a function name() from an address that it assumed to be the contract IntendedTarget.
- However, the address was actually another smart contract
WrongImplementation
that does not implement thename()
. - The smart contract
WrongImplementation
has properly implemented a fallback function. - However, this results in a revert.
This seems strange as the fallback function is present and should be invoked anyway. But it simply reverts and we couldn’t get it to execute anything in the fallback function. Later we noticed that if we changed the declaration of view from the function name()
, then the function call passes. With further investigation, we have the conclusion above.
Reference: https://solidity.readthedocs.io/en/v0.5.3/contracts.html#view-functions