diff --git a/system-contracts/contracts/EvmEmulator.yul b/system-contracts/contracts/EvmEmulator.yul index 12f70efe4..ab5b4deb3 100644 --- a/system-contracts/contracts/EvmEmulator.yul +++ b/system-contracts/contracts/EvmEmulator.yul @@ -20,6 +20,7 @@ object "EvmEmulator" { } mstore(bytecodeLengthOffset, size) + mstore(EMPTY_CODE_OFFSET(), 0) copyActivePtrData(bytecodeOffset, 0, size) } @@ -146,10 +147,15 @@ object "EvmEmulator" { max := mul(2, MAX_POSSIBLE_DEPLOYED_BYTECODE()) // EIP-3860 } - function MEM_OFFSET() -> offset { + // reserved empty slot to simplify PUSH N opcodes + function EMPTY_CODE_OFFSET() -> offset { offset := add(BYTECODE_OFFSET(), MAX_POSSIBLE_ACTIVE_BYTECODE()) } + function MEM_OFFSET() -> offset { + offset := add(EMPTY_CODE_OFFSET(), 32) + } + function MEM_OFFSET_INNER() -> offset { offset := add(MEM_OFFSET(), 32) } @@ -241,20 +247,18 @@ object "EvmEmulator" { } } - // It is the responsibility of the caller to ensure that ip >= BYTECODE_OFFSET + 32 - function readIP(ip,maxAcceptablePos) -> opcode { - if gt(ip, maxAcceptablePos) { - revert(0, 0) + // It is the responsibility of the caller to ensure that ip is correct + function readIP(ip, bytecodeEndOffset) -> opcode { + if lt(ip, bytecodeEndOffset) { + opcode := and(mload(sub(ip, 31)), 0xff) } - - opcode := and(mload(sub(ip, 31)), 0xff) + // STOP else } - function readBytes(start, maxAcceptablePos,length) -> value { - if gt(add(start,sub(length,1)), maxAcceptablePos) { - revert(0, 0) - } - value := shr(mul(8,sub(32,length)),mload(start)) + // It is the responsibility of the caller to ensure that start and length is correct + function readBytes(start, length) -> value { + value := shr(mul(8, sub(32, length)), mload(start)) + // will be padded by zeroes if out of bounds (we have reserved EMPTY_CODE_OFFSET() slot) } function getCodeAddress() -> addr { @@ -389,6 +393,7 @@ object "EvmEmulator" { MAX_POSSIBLE_DEPLOYED_BYTECODE() ) + mstore(EMPTY_CODE_OFFSET(), 0) mstore(BYTECODE_OFFSET(), codeLen) } @@ -1246,13 +1251,12 @@ object "EvmEmulator" { // instruction pointer - index to next instruction. Not called pc because it's an // actual yul/evm instruction. let ip := add(BYTECODE_OFFSET(), 32) - let opcode let stackHead - let maxAcceptablePos := add(add(BYTECODE_OFFSET(), mload(BYTECODE_OFFSET())), 31) + let bytecodeEndOffset := add(add(BYTECODE_OFFSET(), mload(BYTECODE_OFFSET())), 32) for { } true { } { - opcode := readIP(ip,maxAcceptablePos) + let opcode := readIP(ip, bytecodeEndOffset) switch opcode case 0x00 { // OP_STOP @@ -1959,7 +1963,7 @@ object "EvmEmulator" { ip := add(add(BYTECODE_OFFSET(), 32), counter) // Check next opcode is JUMPDEST - let nextOpcode := readIP(ip,maxAcceptablePos) + let nextOpcode := readIP(ip, bytecodeEndOffset) if iszero(eq(nextOpcode, 0x5B)) { panic() } @@ -1985,7 +1989,7 @@ object "EvmEmulator" { ip := add(add(BYTECODE_OFFSET(), 32), counter) // Check next opcode is JUMPDEST - let nextOpcode := readIP(ip, maxAcceptablePos) + let nextOpcode := readIP(ip, bytecodeEndOffset) if iszero(eq(nextOpcode, 0x5B)) { panic() } @@ -2074,7 +2078,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 1) + let value := readBytes(ip, 1) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 1) @@ -2083,7 +2087,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 2) + let value := readBytes(ip, 2) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 2) @@ -2092,7 +2096,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 3) + let value := readBytes(ip, 3) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 3) @@ -2101,7 +2105,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 4) + let value := readBytes(ip, 4) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 4) @@ -2110,7 +2114,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 5) + let value := readBytes(ip, 5) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 5) @@ -2119,7 +2123,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 6) + let value := readBytes(ip, 6) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 6) @@ -2128,7 +2132,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 7) + let value := readBytes(ip, 7) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 7) @@ -2137,7 +2141,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 8) + let value := readBytes(ip, 8) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 8) @@ -2146,7 +2150,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 9) + let value := readBytes(ip, 9) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 9) @@ -2155,7 +2159,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 10) + let value := readBytes(ip, 10) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 10) @@ -2164,7 +2168,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 11) + let value := readBytes(ip, 11) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 11) @@ -2173,7 +2177,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 12) + let value := readBytes(ip, 12) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 12) @@ -2182,7 +2186,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 13) + let value := readBytes(ip, 13) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 13) @@ -2191,7 +2195,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 14) + let value := readBytes(ip, 14) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 14) @@ -2200,7 +2204,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 15) + let value := readBytes(ip, 15) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 15) @@ -2209,7 +2213,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 16) + let value := readBytes(ip, 16) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 16) @@ -2218,7 +2222,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 17) + let value := readBytes(ip, 17) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 17) @@ -2227,7 +2231,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 18) + let value := readBytes(ip, 18) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 18) @@ -2236,7 +2240,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 19) + let value := readBytes(ip, 19) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 19) @@ -2245,7 +2249,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 20) + let value := readBytes(ip, 20) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 20) @@ -2254,7 +2258,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 21) + let value := readBytes(ip, 21) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 21) @@ -2263,7 +2267,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 22) + let value := readBytes(ip, 22) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 22) @@ -2272,7 +2276,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 23) + let value := readBytes(ip, 23) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 23) @@ -2281,7 +2285,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 24) + let value := readBytes(ip, 24) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 24) @@ -2290,7 +2294,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 25) + let value := readBytes(ip, 25) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 25) @@ -2299,7 +2303,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 26) + let value := readBytes(ip, 26) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 26) @@ -2308,7 +2312,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 27) + let value := readBytes(ip, 27) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 27) @@ -2317,7 +2321,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 28) + let value := readBytes(ip, 28) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 28) @@ -2326,7 +2330,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 29) + let value := readBytes(ip, 29) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 29) @@ -2335,7 +2339,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 30) + let value := readBytes(ip, 30) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 30) @@ -2344,7 +2348,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 31) + let value := readBytes(ip, 31) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 31) @@ -2353,7 +2357,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 32) + let value := readBytes(ip, 32) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 32) @@ -3162,10 +3166,15 @@ object "EvmEmulator" { max := mul(2, MAX_POSSIBLE_DEPLOYED_BYTECODE()) // EIP-3860 } - function MEM_OFFSET() -> offset { + // reserved empty slot to simplify PUSH N opcodes + function EMPTY_CODE_OFFSET() -> offset { offset := add(BYTECODE_OFFSET(), MAX_POSSIBLE_ACTIVE_BYTECODE()) } + function MEM_OFFSET() -> offset { + offset := add(EMPTY_CODE_OFFSET(), 32) + } + function MEM_OFFSET_INNER() -> offset { offset := add(MEM_OFFSET(), 32) } @@ -3257,20 +3266,18 @@ object "EvmEmulator" { } } - // It is the responsibility of the caller to ensure that ip >= BYTECODE_OFFSET + 32 - function readIP(ip,maxAcceptablePos) -> opcode { - if gt(ip, maxAcceptablePos) { - revert(0, 0) + // It is the responsibility of the caller to ensure that ip is correct + function readIP(ip, bytecodeEndOffset) -> opcode { + if lt(ip, bytecodeEndOffset) { + opcode := and(mload(sub(ip, 31)), 0xff) } - - opcode := and(mload(sub(ip, 31)), 0xff) + // STOP else } - function readBytes(start, maxAcceptablePos,length) -> value { - if gt(add(start,sub(length,1)), maxAcceptablePos) { - revert(0, 0) - } - value := shr(mul(8,sub(32,length)),mload(start)) + // It is the responsibility of the caller to ensure that start and length is correct + function readBytes(start, length) -> value { + value := shr(mul(8, sub(32, length)), mload(start)) + // will be padded by zeroes if out of bounds (we have reserved EMPTY_CODE_OFFSET() slot) } function getCodeAddress() -> addr { @@ -3405,6 +3412,7 @@ object "EvmEmulator" { MAX_POSSIBLE_DEPLOYED_BYTECODE() ) + mstore(EMPTY_CODE_OFFSET(), 0) mstore(BYTECODE_OFFSET(), codeLen) } @@ -4262,13 +4270,12 @@ object "EvmEmulator" { // instruction pointer - index to next instruction. Not called pc because it's an // actual yul/evm instruction. let ip := add(BYTECODE_OFFSET(), 32) - let opcode let stackHead - let maxAcceptablePos := add(add(BYTECODE_OFFSET(), mload(BYTECODE_OFFSET())), 31) + let bytecodeEndOffset := add(add(BYTECODE_OFFSET(), mload(BYTECODE_OFFSET())), 32) for { } true { } { - opcode := readIP(ip,maxAcceptablePos) + let opcode := readIP(ip, bytecodeEndOffset) switch opcode case 0x00 { // OP_STOP @@ -4975,7 +4982,7 @@ object "EvmEmulator" { ip := add(add(BYTECODE_OFFSET(), 32), counter) // Check next opcode is JUMPDEST - let nextOpcode := readIP(ip,maxAcceptablePos) + let nextOpcode := readIP(ip, bytecodeEndOffset) if iszero(eq(nextOpcode, 0x5B)) { panic() } @@ -5001,7 +5008,7 @@ object "EvmEmulator" { ip := add(add(BYTECODE_OFFSET(), 32), counter) // Check next opcode is JUMPDEST - let nextOpcode := readIP(ip, maxAcceptablePos) + let nextOpcode := readIP(ip, bytecodeEndOffset) if iszero(eq(nextOpcode, 0x5B)) { panic() } @@ -5090,7 +5097,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 1) + let value := readBytes(ip, 1) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 1) @@ -5099,7 +5106,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 2) + let value := readBytes(ip, 2) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 2) @@ -5108,7 +5115,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 3) + let value := readBytes(ip, 3) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 3) @@ -5117,7 +5124,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 4) + let value := readBytes(ip, 4) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 4) @@ -5126,7 +5133,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 5) + let value := readBytes(ip, 5) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 5) @@ -5135,7 +5142,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 6) + let value := readBytes(ip, 6) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 6) @@ -5144,7 +5151,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 7) + let value := readBytes(ip, 7) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 7) @@ -5153,7 +5160,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 8) + let value := readBytes(ip, 8) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 8) @@ -5162,7 +5169,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 9) + let value := readBytes(ip, 9) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 9) @@ -5171,7 +5178,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 10) + let value := readBytes(ip, 10) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 10) @@ -5180,7 +5187,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 11) + let value := readBytes(ip, 11) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 11) @@ -5189,7 +5196,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 12) + let value := readBytes(ip, 12) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 12) @@ -5198,7 +5205,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 13) + let value := readBytes(ip, 13) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 13) @@ -5207,7 +5214,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 14) + let value := readBytes(ip, 14) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 14) @@ -5216,7 +5223,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 15) + let value := readBytes(ip, 15) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 15) @@ -5225,7 +5232,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 16) + let value := readBytes(ip, 16) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 16) @@ -5234,7 +5241,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 17) + let value := readBytes(ip, 17) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 17) @@ -5243,7 +5250,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 18) + let value := readBytes(ip, 18) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 18) @@ -5252,7 +5259,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 19) + let value := readBytes(ip, 19) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 19) @@ -5261,7 +5268,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 20) + let value := readBytes(ip, 20) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 20) @@ -5270,7 +5277,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 21) + let value := readBytes(ip, 21) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 21) @@ -5279,7 +5286,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 22) + let value := readBytes(ip, 22) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 22) @@ -5288,7 +5295,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 23) + let value := readBytes(ip, 23) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 23) @@ -5297,7 +5304,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 24) + let value := readBytes(ip, 24) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 24) @@ -5306,7 +5313,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 25) + let value := readBytes(ip, 25) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 25) @@ -5315,7 +5322,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 26) + let value := readBytes(ip, 26) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 26) @@ -5324,7 +5331,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 27) + let value := readBytes(ip, 27) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 27) @@ -5333,7 +5340,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 28) + let value := readBytes(ip, 28) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 28) @@ -5342,7 +5349,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 29) + let value := readBytes(ip, 29) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 29) @@ -5351,7 +5358,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 30) + let value := readBytes(ip, 30) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 30) @@ -5360,7 +5367,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 31) + let value := readBytes(ip, 31) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 31) @@ -5369,7 +5376,7 @@ object "EvmEmulator" { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 32) + let value := readBytes(ip, 32) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 32) diff --git a/system-contracts/evm-emulator/EvmEmulator.template.yul b/system-contracts/evm-emulator/EvmEmulator.template.yul index 02571acf5..db7499ec3 100644 --- a/system-contracts/evm-emulator/EvmEmulator.template.yul +++ b/system-contracts/evm-emulator/EvmEmulator.template.yul @@ -20,6 +20,7 @@ object "EvmEmulator" { } mstore(bytecodeLengthOffset, size) + mstore(EMPTY_CODE_OFFSET(), 0) copyActivePtrData(bytecodeOffset, 0, size) } diff --git a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul index 6984bbb91..b93e7dc8b 100644 --- a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul @@ -82,10 +82,15 @@ function MAX_POSSIBLE_INIT_BYTECODE() -> max { max := mul(2, MAX_POSSIBLE_DEPLOYED_BYTECODE()) // EIP-3860 } -function MEM_OFFSET() -> offset { +// reserved empty slot to simplify PUSH N opcodes +function EMPTY_CODE_OFFSET() -> offset { offset := add(BYTECODE_OFFSET(), MAX_POSSIBLE_ACTIVE_BYTECODE()) } +function MEM_OFFSET() -> offset { + offset := add(EMPTY_CODE_OFFSET(), 32) +} + function MEM_OFFSET_INNER() -> offset { offset := add(MEM_OFFSET(), 32) } @@ -177,20 +182,18 @@ function checkOverflow(data1, data2) { } } -// It is the responsibility of the caller to ensure that ip >= BYTECODE_OFFSET + 32 -function readIP(ip,maxAcceptablePos) -> opcode { - if gt(ip, maxAcceptablePos) { - revert(0, 0) +// It is the responsibility of the caller to ensure that ip is correct +function readIP(ip, bytecodeEndOffset) -> opcode { + if lt(ip, bytecodeEndOffset) { + opcode := and(mload(sub(ip, 31)), 0xff) } - - opcode := and(mload(sub(ip, 31)), 0xff) + // STOP else } -function readBytes(start, maxAcceptablePos,length) -> value { - if gt(add(start,sub(length,1)), maxAcceptablePos) { - revert(0, 0) - } - value := shr(mul(8,sub(32,length)),mload(start)) +// It is the responsibility of the caller to ensure that start and length is correct +function readBytes(start, length) -> value { + value := shr(mul(8, sub(32, length)), mload(start)) + // will be padded by zeroes if out of bounds (we have reserved EMPTY_CODE_OFFSET() slot) } function getCodeAddress() -> addr { @@ -325,6 +328,7 @@ function getDeployedBytecode() { MAX_POSSIBLE_DEPLOYED_BYTECODE() ) + mstore(EMPTY_CODE_OFFSET(), 0) mstore(BYTECODE_OFFSET(), codeLen) } diff --git a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul index 52d04d072..319edb7e0 100644 --- a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul @@ -3,13 +3,12 @@ let sp := sub(STACK_OFFSET(), 32) // instruction pointer - index to next instruction. Not called pc because it's an // actual yul/evm instruction. let ip := add(BYTECODE_OFFSET(), 32) -let opcode let stackHead -let maxAcceptablePos := add(add(BYTECODE_OFFSET(), mload(BYTECODE_OFFSET())), 31) +let bytecodeEndOffset := add(add(BYTECODE_OFFSET(), mload(BYTECODE_OFFSET())), 32) for { } true { } { - opcode := readIP(ip,maxAcceptablePos) + let opcode := readIP(ip, bytecodeEndOffset) switch opcode case 0x00 { // OP_STOP @@ -716,7 +715,7 @@ for { } true { } { ip := add(add(BYTECODE_OFFSET(), 32), counter) // Check next opcode is JUMPDEST - let nextOpcode := readIP(ip,maxAcceptablePos) + let nextOpcode := readIP(ip, bytecodeEndOffset) if iszero(eq(nextOpcode, 0x5B)) { panic() } @@ -742,7 +741,7 @@ for { } true { } { ip := add(add(BYTECODE_OFFSET(), 32), counter) // Check next opcode is JUMPDEST - let nextOpcode := readIP(ip, maxAcceptablePos) + let nextOpcode := readIP(ip, bytecodeEndOffset) if iszero(eq(nextOpcode, 0x5B)) { panic() } @@ -831,7 +830,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 1) + let value := readBytes(ip, 1) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 1) @@ -840,7 +839,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 2) + let value := readBytes(ip, 2) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 2) @@ -849,7 +848,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 3) + let value := readBytes(ip, 3) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 3) @@ -858,7 +857,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 4) + let value := readBytes(ip, 4) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 4) @@ -867,7 +866,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 5) + let value := readBytes(ip, 5) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 5) @@ -876,7 +875,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 6) + let value := readBytes(ip, 6) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 6) @@ -885,7 +884,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 7) + let value := readBytes(ip, 7) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 7) @@ -894,7 +893,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 8) + let value := readBytes(ip, 8) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 8) @@ -903,7 +902,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 9) + let value := readBytes(ip, 9) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 9) @@ -912,7 +911,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 10) + let value := readBytes(ip, 10) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 10) @@ -921,7 +920,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 11) + let value := readBytes(ip, 11) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 11) @@ -930,7 +929,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 12) + let value := readBytes(ip, 12) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 12) @@ -939,7 +938,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 13) + let value := readBytes(ip, 13) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 13) @@ -948,7 +947,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 14) + let value := readBytes(ip, 14) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 14) @@ -957,7 +956,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 15) + let value := readBytes(ip, 15) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 15) @@ -966,7 +965,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 16) + let value := readBytes(ip, 16) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 16) @@ -975,7 +974,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 17) + let value := readBytes(ip, 17) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 17) @@ -984,7 +983,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 18) + let value := readBytes(ip, 18) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 18) @@ -993,7 +992,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 19) + let value := readBytes(ip, 19) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 19) @@ -1002,7 +1001,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 20) + let value := readBytes(ip, 20) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 20) @@ -1011,7 +1010,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 21) + let value := readBytes(ip, 21) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 21) @@ -1020,7 +1019,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 22) + let value := readBytes(ip, 22) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 22) @@ -1029,7 +1028,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 23) + let value := readBytes(ip, 23) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 23) @@ -1038,7 +1037,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 24) + let value := readBytes(ip, 24) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 24) @@ -1047,7 +1046,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 25) + let value := readBytes(ip, 25) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 25) @@ -1056,7 +1055,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 26) + let value := readBytes(ip, 26) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 26) @@ -1065,7 +1064,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 27) + let value := readBytes(ip, 27) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 27) @@ -1074,7 +1073,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 28) + let value := readBytes(ip, 28) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 28) @@ -1083,7 +1082,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 29) + let value := readBytes(ip, 29) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 29) @@ -1092,7 +1091,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 30) + let value := readBytes(ip, 30) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 30) @@ -1101,7 +1100,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 31) + let value := readBytes(ip, 31) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 31) @@ -1110,7 +1109,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 3) ip := add(ip, 1) - let value := readBytes(ip, maxAcceptablePos, 32) + let value := readBytes(ip, 32) sp, stackHead := pushStackItem(sp, value, stackHead) ip := add(ip, 32)