Solidity Static Call – Making a Static Call to a Non-Static Function Without Changing Blockchain State

blockchaincontract-developmentsoliditystatic-calluniswap

Ive seen that the web interface from Uniswap is making a "fake" call to the contract holding the liquidity positions, and claims all fees (.collect(..)) without actually claiming them. Meaning they fake a non static call to be executed without changing the actual blockchain state.

My question now, is this also possible in the EVM by a smart contract itself? In other words, is there a way to make a static call to a function that is not static to only get the desired return value without changing blockchain state?

Best Answer

By definition of EIP-214 any state change within a static call will cause an error. So if you define your function as view or pure this will not be possible, as this indicates the calling contract that they should use staticcall.

BUT if you want to write a method and don't care about the view or pure you can do a little trick.

You create a method that will perform the call, encode the response (success, data) into a bytes and then revert via assembly with these bytes, therefore reverting the state changes. You can now call this function from another function, catch this error and process the results.

Gnosis has written utils for this: https://github.com/gnosis/util-contracts/blob/main/contracts/storage/StorageAccessible.sol

Hopefully this can be simplified once Solidity allows catching custom errors. As of now you require assembly to do this without wasting too much gas.

Related Topic