Discussion topic for EIP-8173: Foundations of EVM Control Flow
Update Log
- 2026-03-27: initial draft
External Reviews
Outstanding Issues
None as of 2026-03-27.
Discussion topic for EIP-8173: Foundations of EVM Control Flow
None as of 2026-03-27.
Thank you for elaborating on this topic. There’s a few more points that I think should be addressed by this document.
Hello @frangio. EIP-8173 isn’t merged yet, so I won’t try to give a full response until it is.
JUMP, so you have to directly translate it to a dynamic jump in the target code – if the target has one. If it doesn’t you have to generate some sort of if/else chain over every JUMPDEST in the source code. So it’s a nasty attack surface. Most CPUs have some sort of dynamic jump, but not all possible targets will.MAGIC code where all JUMPs have been validated at CREATE time to take a static argument. The reason to support them outside of MAGIC code is of course backwards compatibility.One of the difficulties is while you can certainly compile the code; you can’t really optimize or analyse it beyond a certain point.
This is due to a single smart contract acting like a single function of 28kB with random jumps into every other control flow structure; which is a structurally very hard thing to reason about.
Right. There are any number of ways that the lack of structure hurts.
… The full benefits of static control flow are only available to
MAGICcode where allJUMPs have been validated atCREATEtime to take a static argument. The reason to support them outside of MAGIC code is of course backwards compatibility.
Another reason to support calls and returns in “legacy” code a is that there are useful applications of dynamic jumps that don’t satisfy the validity rules in EIP-7979. E.g. EOF uses different validity rules that promise more properties than EIP-7979, at the expense of more stringent rules on code organization. And you can do things like build arrays on the stack that can’t be done in validated code. So I prefer to provide a useful facility without forcing people to use it.
It’s not important that at runtime
gasisn’t random or that thejumpwill most often fail, what matters is that because the jump destination is taken from the stack it is impossible to know a priori where the jumps go, so every path must be explored.
So, should we limit the maximum number of paths in runtime code during initialization? For example, we set a limit (ΣJUMP + ΣJUMPI) * ΣJUMPDEST <= MAX_PATH for the legacy EVM.
I’m not sure I follow. I’m not proposing to put any new limitations on legacy code.