-
Notifications
You must be signed in to change notification settings - Fork 537
Description
9.4.3. Jump Destination Validity. We previously used D
as the function to determine the set of valid jump destinations given the code that is being run. We define this
as any position in the code occupied by a JUMPDEST
instruction.
All such positions must be on valid instruction boundaries, rather than sitting in the data portion of PUSH
operations and must appear within the explicitly defined
portion of the code (rather than in the implicitly defined
STOP operations that trail it).
Consider the following assembly code:
dataSize(sub_0)
dataOffset(sub_0)
0x00
codecopy
dataSize(sub_0)
0x00
return
stop
sub_0: assembly {
tag1
jump
stop
stop
tag1:
0xeeeeeeee
0x00
mstore
0x20
0x00
return
}
This translates to 0x601461000e60003960146000f3006100065600005b63eeeeeeee60005260206000f3. If this contract is deployed and it receives a transaction/call, it returns 0x00000000000000000000000000000000000000000000000000000000eeeeeeee. An example of this execution was ran at https://ropsten.etherscan.io/tx/0x6c300851fc63bb91829041acddd49c440720ca095061f4d164e53e9abce4d781.
Consider that we change the above bytecode by replacing the 2nd stop instruction with PUSH4 (0x63). We obtain 0x601461000e60003960146000f3006100065600635b63eeeeeeee60005260206000f3. If this contract is deployed and it receives a transaction/call, it reverts with Invalid JUMP destination: https://ropsten.etherscan.io/tx/0x81c674bb22b7171f1f0bd3ee98b09c35ef5e9874c7fc232821eb1b9542a363c0. This happens even though the 0x63 (PUSH4) instruction is never reachable, therefore not executable.
This behavior is not obvious, not even from the description of the Yellow Paper and I doubt it is the intended behavior. Nonetheless, clients are implementing it https://github.com/ethereumjs/ethereumjs-monorepo/blob/93c4c4ad182d4b4be54b6346aab70f615fb21bb8/packages/vm/src/evm/interpreter.ts#L263-L283.