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.
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:
monad/category/execution/monad/monad_precompiles.cpp
Lines 37 to 39 in 46dc849
The staking dispatch function which returns looks up function pointers and gas to be used.
monad/category/execution/monad/staking/staking_contract.cpp
Line 714 in 46dc849
Approach:
Just some ideas
It's important that it is easy to verify CALL/STATICCALL and hard to make a future mistake.
The
precompile_dispatchfile 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_precompileshould 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.