paradigmxyz
revmc
Blog
Docs
Changelog
Blog
Docs
Changelog
Overview
Branches
Benchmarks
Runs
Performance History
Latest Results
chore: fix jump resolution script
main
1 day ago
tst
dani/local-jump-resolution
1 day ago
Merge branch 'main' into dani/local-jump-resolution
dani/local-jump-resolution
1 day ago
feat: provenance-based return detection for PCR Replace the opcode whitelist for private function return detection with a stack provenance simulation. Tracks whether each stack slot originates from the block's entry stack (Input) or was produced in-block (Local). A dynamic JUMP qualifies as a private return if its operand has Input provenance and the block contains no unsafe opcodes (TLOAD/TSTORE, CALL-family, CREATE-family). This resolves weth (0 unresolved), usdc_proxy (0 unresolved), and univ2_router (0 unresolved) by detecting return blocks that contain arithmetic, memory ops, SLOAD, BALANCE, LOG, etc.
dani/local-jump-resolution
2 days ago
feat: provenance-based return detection for PCR Replace the opcode whitelist for private function return detection with a stack provenance simulation. Tracks whether each stack slot originates from the block's entry stack (Input) or was produced in-block (Local). A dynamic JUMP qualifies as a private return if its operand has Input provenance and the block contains no unsafe opcodes (TLOAD/TSTORE, CALL-family, CREATE-family). This resolves weth (0 unresolved), usdc_proxy (0 unresolved), and univ2_router (0 unresolved) by detecting return blocks that contain arithmetic, memory ops, SLOAD, BALANCE, LOG, etc.
dani/local-jump-resolution
2 days ago
fix(context): remove unsound `call_with_interpreter_and_memory` (#276) \`EvmCompilerFn::call_with_interpreter_and_memory\` swapped the caller-provided \`SharedMemory\` into \`interpreter.memory\` but never saved/restored the interpreter's original memory object. After the compiled function returned, \`interpreter.memory\` was left as \`SharedMemory::invalid()\` (\`buffer: None\`). Any subsequent memory access — such as inserting a CALL outcome via the standard revm path — would panic in debug builds or hit \`unwrap_unchecked()\` on \`None\` in release builds (UB). This function was unused in-tree and the bug makes it unsound, so remove it entirely rather than trying to fix it.
main
2 days ago
fix(context): remove unsound `call_with_interpreter_and_memory` This function swapped the caller-provided `SharedMemory` into `interpreter.memory` but never saved/restored the interpreter's original memory. After the call, `interpreter.memory` was left as `SharedMemory::invalid()`, causing a panic in debug builds or UB in release builds on any subsequent memory access (e.g. inserting a CALL outcome).
dani/remove-call-with-interpreter-and-memory
2 days ago
fix(dedup): merge multi_jump_targets when deduplicating MULTI_JUMP dispatcher blocks (#273) When two byte-identical MULTI_JUMP dispatcher blocks have their target blocks deduped first, their successor block IDs become identical, causing the dedup pass to merge them. However, only the canonical dispatcher's `multi_jump_targets` were preserved — valid case PCs unique to the eliminated dispatcher were lost, causing valid jumps to fall into the `InvalidJump` trap at runtime. This is a consensus-critical compiler soundness bug: the interpreter returns `Stop` while the JIT returns `InvalidJump` for valid bytecode. ### Root cause The failure requires two dedup rounds: 1. Four identical `JUMPDEST; STOP` return blocks are deduped first. 2. During `rebuild_cfg()`, two different byte-identical dispatcher blocks now both resolve to the same successor block IDs because their original target PCs were mapped through `redirects`. 3. Because `DedupKey` only compares `(bytes, succs)`, the two dispatcher blocks collide and one is deduped away. 4. Translation never visits the dead dispatcher's terminator because `iter_insts()` skips dead instructions. 5. The surviving dispatcher's switch contains only its own original case PCs. Valid PCs unique to the removed dispatcher fall into the default `InvalidJump` trap. ### Fix When deduping a MULTI_JUMP block, union the duplicate's `multi_jump_targets` into the canonical block's targets so the emitted switch covers all valid case PCs from both dispatchers. ### POC ``` cargo run -p revmc-cli -- run custom \ --code 5f3560165760203560105760286030565b602a6030565b602035602257602c6032565b602e6032565b005b005b005b005b565b56 \ --calldata 0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000 ``` Before: `InstructionResult::InvalidJump` After: `InstructionResult::Stop` (matches interpreter)
main
2 days ago
Latest Branches
CodSpeed Performance Gauge
-26%
feat: local call/return detection with context-sensitive resolution
#222
1 day ago
5b9b6f2
dani/local-jump-resolution
CodSpeed Performance Gauge
0%
fix(context): remove unsound `call_with_interpreter_and_memory`
#276
2 days ago
2b133b9
dani/remove-call-with-interpreter-and-memory
CodSpeed Performance Gauge
0%
fix(dedup): merge multi_jump_targets when deduplicating MULTI_JUMP dispatcher blocks
#273
2 days ago
32ae22b
dani/fix-dedup-multi-jump-targets
© 2026 CodSpeed Technology
Home
Terms
Privacy
Docs