Post

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 opCode CALL.
  • 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 the name().
  • 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

This post is licensed under CC BY 4.0 by the author.