This page is a placeholder. All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.
Overview
Opcode: 0x5b
Introduced: Frontier (EVM genesis)
JUMPDEST marks a valid destination for JUMP and JUMPI instructions. It’s the only opcode that JUMP/JUMPI can target - attempting to jump to any other instruction causes InvalidJump error.
This is a critical security feature that prevents arbitrary code execution by restricting where jumps can land.
Specification
Stack Input: None
Stack Output: None
Gas Cost: 1 (JumpdestGas)
Operation:
JUMPDEST is effectively a no-op that validates jump destinations.
Behavior
JUMPDEST serves two purposes:
At execution time:
- Consumes 1 gas (cheapest opcode)
- Increments program counter
- No other side effects (no stack/memory changes)
At validation time (before execution):
- Analyzed during bytecode deployment/validation
- Positions marked as valid jump destinations
- Used to validate JUMP/JUMPI targets
Key Characteristics:
- Only valid target for JUMP/JUMPI
- Cannot be inside PUSH data
- Multiple JUMPDESTs can exist in bytecode
- Can be consecutive (JUMPDEST JUMPDEST is valid)
Examples
Basic JUMPDEST
Valid Jump Target
JUMPDEST in PUSH Data (Invalid)
Consecutive JUMPDESTs
Bytecode:
All three positions are valid jump targets.
Gas Cost
Cost: 1 gas (JumpdestGas)
JUMPDEST is the cheapest opcode in the EVM.
Comparison:
- JUMPDEST: 1 gas (cheapest)
- PC: 2 gas
- PUSH1-32: 3 gas
- ADD/SUB: 3 gas
- JUMP: 8 gas
Jump Operation Total Cost:
Edge Cases
Empty Stack
Out of Gas
JUMPDEST at End
Multiple JUMPDESTs Same Location
Common Usage
Function Entry Points
Every internal function starts with JUMPDEST:
Compiled:
Loop Start
Branch Targets
Jump Table
Implementation
JUMPDEST Validation
Bytecode Analysis
Before execution, bytecode is analyzed to identify valid JUMPDESTs:
Key points:
- Scan bytecode linearly
- Mark JUMPDEST positions (0x5b)
- Skip PUSH data (don’t mark 0x5b inside PUSH as valid)
- Build set of valid destinations
Validation at Jump Time
Testing
Test Coverage
Security
Critical Security Feature
JUMPDEST validation prevents arbitrary code execution:
Without JUMPDEST requirement:
With JUMPDEST requirement:
This prevents:
- Jumping into middle of multi-byte instructions
- Jumping into PUSH data
- Executing data as code
- Arbitrary control flow hijacking
PUSH Data vs Real JUMPDEST
Critical distinction:
Only position 3 is a valid jump destination. Position 1 looks like JUMPDEST but is PUSH data.
Validation must:
- Track PUSH boundaries
- Only mark 0x5b as valid if NOT in PUSH data
- Reject jumps to PUSH data even if byte value is 0x5b
Static vs Dynamic Analysis
Static analysis (deployment time):
- Scan bytecode for all JUMPDESTs
- Build valid destination set
- O(n) time complexity, done once
Dynamic validation (execution time):
- Check if jump target is in valid set
- O(1) lookup with hash set
- Fast validation on every JUMP/JUMPI
Malicious Bytecode
Attack attempt:
Jump to position 3 targets PUSH1 opcode, not JUMPDEST → InvalidJump error.
Compiler Behavior
Automatic JUMPDEST Insertion
Solidity automatically inserts JUMPDEST at:
- Function entry points
- Loop starts
- Branch targets
- Case statements
Compiled to:
Optimization
Compilers can optimize unreachable JUMPDESTs:
Optimized bytecode removes unreachable JUMPDEST, saving 1 gas.
Label Resolution
Solidity labels are resolved to JUMPDEST positions at compile time:
Historical Context
JUMPDEST was introduced in Frontier to:
- Prevent arbitrary code execution
- Enable static analysis of control flow
- Distinguish code from data
- Support jump validation without runtime overhead
Alternative designs considered:
- Unrestricted jumps (rejected - too dangerous)
- Jump tables only (rejected - not flexible enough)
- Type system for code pointers (rejected - too complex)
JUMPDEST provides optimal balance of security, flexibility, and performance.
References