foundry
foundry copied to clipboard
"EvmError: NotActivated" when trying to use a deployed contract compiled with Shanghai but with evm_version set to Paris for scripts
Component
Forge, Anvil
Have you ensured that all of these are up to date?
- [X] Foundry
- [X] Foundryup
What version of Foundry are you on?
forge 0.2.0 (fa6b39c 2023-11-04T00:17:54.146286000Z)
What command(s) is the bug in?
No response
Operating System
None
Describe the bug
It seems there are some mixup with anvil evm emulation / forge script simulation when working with different evm versions.
When trying to deploy a contract compiled with Paris using a create2deployer deployed with Shanghai, an error is thrown: EvmError: NotActivated
at the computeAddress
step.
A deployment with ABI Ninja works https://etherscan.io/tx/0x85d5353fa0924f8b0ed23fa624c09000e6d2a531676e256ba1b76f4e693afce3
A computeAddress with ABI Ninja works:
The codeHash used was obtain by compiling contract with evm version set to Paris
But with anvil / forge script computeAddress
fails with EvmError: NotActivated
Here is a repo to replicate the issue https://github.com/obatirou/foundry-bug-replication
It will only pass if the evm version is set to Shanghai in the repo.
CC @Evalir
I'm not sure I understand. you're running anvil and deploying a contract with forge? in that case, both need set their evm version to shanghai. One does not automatically set the other.
I'm not sure I understand. you're running anvil and deploying a contract with forge? in that case, both need set their evm version to shanghai. One does not automatically set the other.
computeAddress
is part of a script that deploys contracts to mainnet that need to be compiled with Paris. They are deployed through a create2deployer that was compiled and deployed with Shanghai version on mainnet here. This script fails with "EvmError: NotActivated"
.
The anvil part was only to reproduce the bug in local, I might miss something here.
@evalir This probably happens because the EVM version for fork in which script is running defaults to the EVM version contracts were compiled with. This is also valid for tests using forking environments.
Right now it is impossible to do fork-testing of contract compiled with paris
which is interacting with contracts compiled with shanghai
, however, this should be possible
Minimal repro for this looks like this:
pragma solidity 0.8.20;
import {Test} from "forge-std/Test.sol";
interface ICreate2Deployer {
function computeAddress(bytes32 salt, bytes32 codeHash) external view returns (address);
}
contract TestEVMVersion is Test {
function test() public {
vm.createSelectFork("mainnet");
ICreate2Deployer(0x35Da41c476fA5c6De066f20556069096A1F39364).computeAddress(bytes32(0), bytes32(0));
}
}
Running forge test -vvv --evm-version paris
will fail with EvmError: NotActivated
while forge test -vvv --evm-version shanghai
will run successfully
This will get worse over the time as more contracts will be deployed with PUSH0, and projects still compiling with paris
will get unexpected reverts duing fork testing.
This can be solved by automatically enabling shanghai for chains from SHANGHAI_ENABLED_CHAINS when running tests/scripts in forks, but it does not seem to be a best fix as this list would have to be updated every time some other chain enables shanghai support
This makes sense, we probably need to decouple these and have:
- One setting to specify which
evm_version
should be passed to solc - Another setting to specify which
evm_version
should be used for execution
Right now those two are coupled
@mds1 I think we can assume that this issue mostly affects projects which are compiling contracts with paris
, but deploying them on Ethereum. This probably means that they are trying to keep their contracts compatible with Ethereum and some other non-shanghai chains at the same time. And they are probably running fork-testing on them via forking cheatcodes.
If we will have global setting for evm_version
, it will affect all forks created via vm.createFork
cheatcodes which is invalid.
Thanks for the clarification. So:
- The existing
evm_version
should only affect solc configuration, not forge's execution environment. - When forge has an RPC URL (either during tests after selecting a fork, or during a script simulation), forge should use the correct execution environment of that fork.
- This should be a function of block number too, i.e. it accounts for when upgrades occurred.
- Consequence here is forge needs a mapping from chain ID to a list of forks and the block numbers at which they occurred. (For mainnet this is here)
- If there is no RPC, the execution environment defaults to the
evm_version
selected.
I think that should solve this issue, and avoid the need for an extra flag. How does that sound?
Yes, this sounds reasonable.
This should be a function of block number too, i.e. it accounts for when upgrades occurred.
Managing such mapping seems like something out of foundry's scope and it will be hard to include all existing chains into it.
It might make sense to also add a vm.createFork(string rpcUrl, EvmVersion evmVersion)
(EvmVersion
is a enum), so that users deploying and testing contracts on chains supporting shanghai
will be able to run tests successfuly, despite foundry not including this chain in the mapping for some reason
I am getting the same error when trying to interact with a contract deployed on goerli testnet,
I didn't deploy it using foundry, someone else deployed it using remix, the evm_version was set to default evmVersion so it should be shanghai.
somewhat related #6440
same issue here when interactivating with a contract created by create2
, I append the flag --evm-version shanghai
to supress this error.
same issue here when interactivating with a contract created by
create2
, I append the flag--evm-version shanghai
to supress this error.
I am on solc 0.8.22 and shanghai (set both in foundry.toml as a flag when running forge test
).
Yet still am stuck getting [NotActivated] EvmError: NotActivated
Interestingly, this is happening on an already-deployed create2 factory I call to deploy a new contract using create2. So i'm wondering what create2 has to do with anything (if something?).
here is the factory deployer: 0x3eA13660e4B4319A1418c5A5e9Fe98263e65AC4f
EDIT: Found the issue. The contract on mainnet used a new opcode from cancun upgrade (MCOPY). So my attempts to run using shanghai failed, but --evm-version cancun
succeded.