Open albertov19 opened 7 months ago
We ran the same test but against a regular ERC-20 and it seems that our precompile does not support eth_getStorageAt
queries. Why is this not done via a simple eth_call
?
Thanks in advance
thanks for flagging, this sounds weird indeed.
I'd appreciate if you could put this simple example into a minimal repro, so I don't have set it up manually what are you're cli args?
We never see the eth_call to fetch the balance of the address on the precompile. Our theory is that Foundry is doing some checks against the bytecode returned by eth_getCode.
The way fork testing works is by fetching bytecode of the contract via eth_getCode
and executing it instead of making eth_call
s. This is needed because eth_call
s does not let you mutate and track changes of the EVM state.
This limitation is explained in Moonbeam docs https://docs.moonbeam.network/builders/build/eth-api/dev-env/foundry/#forking-with-cast-anvil
We never see the eth_call to fetch the balance of the address on the precompile. Our theory is that Foundry is doing some checks against the bytecode returned by eth_getCode.
The way fork testing works is by fetching bytecode of the contract via
eth_getCode
and executing it instead of makingeth_call
s. This is needed becauseeth_call
s does not let you mutate and track changes of the EVM state.This limitation is explained in Moonbeam docs https://docs.moonbeam.network/builders/build/eth-api/dev-env/foundry/#forking-with-cast-anvil
Hey @klkvr thanks for your reply.
The issue is not that, we are well aware. This test was run against a Moonbeam fork that does support precompiles (note the successful JSON RPC eth_call for example).
We realized that the issue is that Moonbeam clients don't support rth_getStoragrAt
for precompiles. We need to add support for this at a client level, but we did not realize that these kind of calls were executed like this and not via eth_call
Is there a way to run tests without eth_getStorageAt
for contract static calls?
Thanks in advance
Yeah, eth_getStorageAt
queries don't work as precompiles do not store any data in the actual smart contract storage.
There is currently no way to run tests without eth_getStorage
as we need those queries to be able to process storage reads happening during execution.
If we'd use eth_call
s, it would only be able to response with data relevant for current mainnet state. That way, if your test mutates state of precompile token (via transfer
), we wouldn't be able to know what the next result of balanceOf
will be. Thus, you wouldn't be able to test any behavior dependent on precompiles state
Yeah,
eth_getStorageAt
queries don't work as precompiles do not store any data in the actual smart contract storage.There is currently no way to run tests without
eth_getStorage
as we need those queries to be able to process storage reads happening during execution.If we'd use
eth_call
s, it would only be able to response with data relevant for current mainnet state. That way, if your test mutates state of precompile token (viatransfer
), we wouldn't be able to know what the next result ofbalanceOf
will be. Thus, you wouldn't be able to test any behavior dependent on precompiles state
Understood.
What happens is not that precompiles do not store any data in the actual smart contract data (which you are correct and they don't), is just that Moonbeam's Ethereum compatibility layer does not have a map for eth_getStorageAt
for precompiles so it looks in the Ethereum emulation layer we run etc.
So we'll have to support this so that devs can run tests against these type of Moonbeam forks.
Is there a way to have Foundry use a custom fork methodology for Moonbeam that is not Anvil? This will allow devs to fork and use precompiles (after we fix the issue of getStorageAt)
Thanks for all your replies!
custom precompile handlers would be possible once we've updated the evm dependency
could you point us to the moonbeam precompiles?
custom precompile handlers would be possible once we've updated the evm dependency
could you point us to the moonbeam precompiles?
Happy to help!
We have the following: https://docs.moonbeam.network/builders/pallets-precompiles/precompiles/
And also a lot of Substrate based assets like DOT is served to our EVM as a precompile as well. Here are the list of such precompiles (that are erc-20)
https://docs.moonbeam.network/builders/interoperability/xcm/xc20/overview/#current-xc20-assets
Hey @mattsse @klkvr, we are happy to help out however we can to make Moonbeam testing more smooth.
Let us know what we can do on our end.
Regards
Component
Forge
Have you ensured that all of these are up to date?
What version of Foundry are you on?
forge 0.2.0 (b174c3a 2024-02-09T00:16:22.953958126Z)
What command(s) is the bug in?
forge test
Operating System
Linux
Describe the bug
We are executing a simple test against a Moonbeam precompile running it against a Moonbeam specific fork that supports their precompiles. We check precompile support by doing a simple
eth_call
to the precompile fetching thebalanceOf
a specific address. The JSON-RPC works, meaning that the fork supports Precompiles.The test is fairly simple, it loads the precompile address through an ERC_20 token interface and calls the
balanceOf
method. We added a console log forHello!
just to understand where it failed, if in the loading the token interface, or executing thebalanceOf
.After running the test, it failed in the
balanceOf
operation. Test logs:In the Moonbeam Fork, we enabled the JSON-RPC trace, meaning we had visibility to all the JSON-RPC requests and responses from the fork itself.
The first weird thing we noticed is that there are a lot of weird
eth_getTransactionCount
,eth_getBalance
andeth_getCode
calls to smart contracts, some of them were not even in the tests! Another weird thing is that these calls referred to values in block0x59
. Moonbeam fork actually builds on top of the latest block of the chain, which is already past 5.4M blocks. For example, this is the JSON-RPC trace for the precompile address before the test fails and there are no more JSON-RPC calls:Note that the bytecode for the precompile is just
REVERT
, but it is set as such so that when doing a address size check it returns something different to zero and the execution understands that the target address is a contract and not an EOA.We never see the
eth_call
to fetch the balance of the address on the precompile. Our theory is that Foundry is doing some checks against the bytecode returned byeth_getCode
.Any ideas?
Thanks in advance