Skip to content

Allow read only staking precompile functions to be called via STATICCALL. #1710

@DanielVF

Description

@DanielVF

Currently, Monad specific precompiles can only be called by a CALL opcode. STATICCALL and DELEGATECALL calls revert. However many of the staking functions are read only, and should be able to be STATICCALL'd so that they can be called from solidity view functions.

This is not urgent, and can be rolled out at a future time since the fix will not break any existing code. It's just currently a bit ugly and pushes uglier code onto LSTs.

Current code:

Code enforcing CALL only in monad_precompiles.cpp:

if (MONAD_UNLIKELY(msg.kind != EVMC_CALL) || (msg.flags != 0)) {
return evmc::Result{evmc_status_code::EVMC_REJECTED};
}

The staking dispatch function which returns looks up function pointers and gas to be used.

StakingContract::precompile_dispatch(byte_string_view &input)

Approach:

Just some ideas

It's important that it is easy to verify CALL/STATICCALL and hard to make a future mistake.

The precompile_dispatch file is the function that knows about which function is selected, and this will be the one that knows which functions should be read only. I would propose that it return a tuple, rather than a pair, with the new parameter inserted in the middle for WRITES and READONLY. (I'm open to better names). By having it as a part of the tuple, it enforces that all dispatchable methods must have a defined CALL/STATICCALL choice.

check_call_monad_precompile should then move the EVMC_CALL check after the method is selected, before the gas is checked, and use the returned type to allow EVMC_STATICCALL when appropriate.

An alternative would be an explicit whitelist of allowed STATICCALL methods. This would be more resistant to copy paste errors, but involve some duplicate code, and information being in two places.

Yet another alternative would be to use the gas pricing data to look up which methods do writes, and set the toggle appropriately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions