@zkasm/zkevm-rom 0.0.1-security → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @zkasm/zkevm-rom might be problematic. Click here for more details.
- package/.eslintrc.js +33 -0
- package/.github/CODEOWNERS +14 -0
- package/.github/ISSUE_TEMPLATE/bug.yml +38 -0
- package/.github/ISSUE_TEMPLATE/feature.yml +26 -0
- package/.github/ISSUE_TEMPLATE/question.yml +26 -0
- package/.github/workflows/main.yaml +40 -0
- package/LICENSE +636 -0
- package/README.md +23 -5
- package/audits/Hexens_Polygon_zkEVM_PUBLIC_27.02.23.pdf +0 -0
- package/audits/Polygon-zkEVM-Public-v1.1-verichains-19-03-2024.pdf +0 -0
- package/audits/zkEVM-ROM-upgrade-1-Spearbit-30-May.pdf +0 -0
- package/audits/zkEVM-ROM-upgrade-2-Spearbit-21-August.pdf +0 -0
- package/audits/zkEVM-engagement-1-Spearbit-27-March.pdf +0 -0
- package/audits/zkEVM-engagement-2-Spearbit-27-March.pdf +0 -0
- package/audits/zkEVM-engagement-3-Spearbit-6-April.pdf +0 -0
- package/counters/README.md +45 -0
- package/counters/counters-executor.js +80 -0
- package/counters/countersConstants.zkasm +370 -0
- package/counters/endIncludes.zkasm +18 -0
- package/counters/initIncludes.zkasm +2 -0
- package/counters/tests/MLOAD32.zkasm +27 -0
- package/counters/tests/MLOADX.zkasm +30 -0
- package/counters/tests/MSTORE32.zkasm +32 -0
- package/counters/tests/MSTOREX.zkasm +36 -0
- package/counters/tests/SHLarith.zkasm +28 -0
- package/counters/tests/SHLarithBit.zkasm +28 -0
- package/counters/tests/SHRarith.zkasm +28 -0
- package/counters/tests/SHRarithBit.zkasm +28 -0
- package/counters/tests/abs.zkasm +29 -0
- package/counters/tests/addBatchHashByteByByte.zkasm +31 -0
- package/counters/tests/computeGasSendCall.zkasm +30 -0
- package/counters/tests/divArith.zkasm +27 -0
- package/counters/tests/expAD.zkasm +30 -0
- package/counters/tests/getLenBits.zkasm +30 -0
- package/counters/tests/getLenBytes.zkasm +32 -0
- package/counters/tests/isEmptyAccount.zkasm +30 -0
- package/counters/tests/mulARITH.zkasm +28 -0
- package/counters/tests/offsetUtil.zkasm +29 -0
- package/counters/tests/opADDMOD.zkasm +28 -0
- package/counters/tests/opAdd.zkasm +27 -0
- package/counters/tests/opBLOCKHASH.zkasm +28 -0
- package/counters/tests/opCALL.zkasm +41 -0
- package/counters/tests/opCALLCODE.zkasm +41 -0
- package/counters/tests/opCALLDATACOPY.zkasm +28 -0
- package/counters/tests/opCALLDATALOAD.zkasm +27 -0
- package/counters/tests/opCODECOPY.zkasm +28 -0
- package/counters/tests/opCREATE.zkasm +35 -0
- package/counters/tests/opCREATE2.zkasm +35 -0
- package/counters/tests/opDELEGATECALL.zkasm +35 -0
- package/counters/tests/opDIV.zkasm +27 -0
- package/counters/tests/opEXP.zkasm +29 -0
- package/counters/tests/opEXTCODECOPY.zkasm +29 -0
- package/counters/tests/opMOD.zkasm +27 -0
- package/counters/tests/opMUL.zkasm +27 -0
- package/counters/tests/opMULMOD.zkasm +28 -0
- package/counters/tests/opRETURN.zkasm +32 -0
- package/counters/tests/opRETURNDATACOPY.zkasm +29 -0
- package/counters/tests/opREVERT.zkasm +32 -0
- package/counters/tests/opSDIV.zkasm +28 -0
- package/counters/tests/opSHA3.zkasm +28 -0
- package/counters/tests/opSIGNEXTEND.zkasm +27 -0
- package/counters/tests/opSMOD.zkasm +28 -0
- package/counters/tests/opSTATICCALL.zkasm +35 -0
- package/counters/tests/opSUB.zkasm +27 -0
- package/counters/tests/saveMem.zkasm +31 -0
- package/docs/opcode-cost-zk-counters.md +315 -0
- package/docs/usage-ecrecover.md +51 -0
- package/index.js +43 -0
- package/main/block-info.zkasm +204 -0
- package/main/constants.zkasm +145 -0
- package/main/ecrecover/addFpEc.zkasm +31 -0
- package/main/ecrecover/checkSqrtFpEc.zkasm +1558 -0
- package/main/ecrecover/constEc.zkasm +13 -0
- package/main/ecrecover/ecrecover.zkasm +280 -0
- package/main/ecrecover/invFnEc.zkasm +44 -0
- package/main/ecrecover/invFpEc.zkasm +45 -0
- package/main/ecrecover/mulFnEc.zkasm +36 -0
- package/main/ecrecover/mulFpEc.zkasm +36 -0
- package/main/ecrecover/mulPointEc.zkasm +311 -0
- package/main/ecrecover/sqFpEc.zkasm +38 -0
- package/main/ecrecover/sqrtFpEc.zkasm +70 -0
- package/main/end.zkasm +4 -0
- package/main/l2-tx-hash.zkasm +159 -0
- package/main/load-change-l2-block-utils.zkasm +11 -0
- package/main/load-change-l2-block.zkasm +28 -0
- package/main/load-tx-rlp-utils.zkasm +72 -0
- package/main/load-tx-rlp.zkasm +431 -0
- package/main/main.zkasm +237 -0
- package/main/map-opcodes.zkasm +274 -0
- package/main/modexp/array_lib/array_add_AGTB.zkasm +123 -0
- package/main/modexp/array_lib/array_add_short.zkasm +85 -0
- package/main/modexp/array_lib/array_div.zkasm +215 -0
- package/main/modexp/array_lib/array_div_long.zkasm +284 -0
- package/main/modexp/array_lib/array_div_short.zkasm +222 -0
- package/main/modexp/array_lib/array_mul.zkasm +97 -0
- package/main/modexp/array_lib/array_mul_long.zkasm +156 -0
- package/main/modexp/array_lib/array_mul_short.zkasm +127 -0
- package/main/modexp/array_lib/array_square.zkasm +246 -0
- package/main/modexp/array_lib/unused/array_add.zkasm +100 -0
- package/main/modexp/array_lib/unused/array_is_odd.zkasm +23 -0
- package/main/modexp/array_lib/unused/array_is_one.zkasm +33 -0
- package/main/modexp/array_lib/unused/array_is_zero.zkasm +34 -0
- package/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +111 -0
- package/main/modexp/array_lib/unused/array_unshift.zkasm +37 -0
- package/main/modexp/array_lib/utils/array_compare.zkasm +82 -0
- package/main/modexp/array_lib/utils/array_trim.zkasm +49 -0
- package/main/modexp/constants.zkasm +5 -0
- package/main/modexp/modexp.zkasm +296 -0
- package/main/modexp/modexp_utils.zkasm +230 -0
- package/main/opcodes/arithmetic.zkasm +357 -0
- package/main/opcodes/block.zkasm +163 -0
- package/main/opcodes/calldata-returndata-code.zkasm +619 -0
- package/main/opcodes/comparison.zkasm +446 -0
- package/main/opcodes/context-information.zkasm +169 -0
- package/main/opcodes/create-terminate-context.zkasm +1011 -0
- package/main/opcodes/crypto.zkasm +96 -0
- package/main/opcodes/flow-control.zkasm +126 -0
- package/main/opcodes/logs.zkasm +193 -0
- package/main/opcodes/stack-operations.zkasm +658 -0
- package/main/opcodes/storage-memory.zkasm +313 -0
- package/main/pairings/BN254/addPointBN254.zkasm +245 -0
- package/main/pairings/BN254/ecAdd.zkasm +312 -0
- package/main/pairings/BN254/ecMul.zkasm +159 -0
- package/main/pairings/BN254/escalarMulBN254.zkasm +155 -0
- package/main/pairings/BN254/lineDiffPointsBN254.zkasm +83 -0
- package/main/pairings/BN254/lineSamePointsBN254.zkasm +96 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm +49 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +236 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +444 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +212 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +228 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm +64 -0
- package/main/pairings/FP12BN254/frob2Fp12BN254.zkasm +80 -0
- package/main/pairings/FP12BN254/frob3Fp12BN254.zkasm +96 -0
- package/main/pairings/FP12BN254/frobFp12BN254.zkasm +96 -0
- package/main/pairings/FP12BN254/inverseFp12BN254.zkasm +289 -0
- package/main/pairings/FP12BN254/mulFp12BN254.zkasm +408 -0
- package/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm +296 -0
- package/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm +291 -0
- package/main/pairings/FP12BN254/squareFp12BN254.zkasm +376 -0
- package/main/pairings/FP2BN254/addFp2BN254.zkasm +19 -0
- package/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm +20 -0
- package/main/pairings/FP2BN254/invFp2BN254.zkasm +66 -0
- package/main/pairings/FP2BN254/mulFp2BN254.zkasm +19 -0
- package/main/pairings/FP2BN254/squareFp2BN254.zkasm +21 -0
- package/main/pairings/FP2BN254/subFp2BN254.zkasm +19 -0
- package/main/pairings/FP4BN254/squareFp4BN254.zkasm +76 -0
- package/main/pairings/FP6BN254/addFp6BN254.zkasm +59 -0
- package/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm +51 -0
- package/main/pairings/FP6BN254/inverseFp6BN254.zkasm +208 -0
- package/main/pairings/FP6BN254/mulFp6BN254.zkasm +201 -0
- package/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm +65 -0
- package/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm +134 -0
- package/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm +128 -0
- package/main/pairings/FP6BN254/squareFp6BN254.zkasm +147 -0
- package/main/pairings/FP6BN254/subFp6BN254.zkasm +59 -0
- package/main/pairings/FPBN254/addFpBN254.zkasm +29 -0
- package/main/pairings/FPBN254/invFpBN254.zkasm +55 -0
- package/main/pairings/FPBN254/mulFpBN254.zkasm +29 -0
- package/main/pairings/FPBN254/reduceFpBN254.zkasm +25 -0
- package/main/pairings/FPBN254/squareFpBN254.zkasm +31 -0
- package/main/pairings/FPBN254/subFpBN254.zkasm +36 -0
- package/main/pairings/FRBN254/reduceFrBN254.zkasm +25 -0
- package/main/pairings/constants.zkasm +62 -0
- package/main/pairings/ecPairing.zkasm +244 -0
- package/main/pairings/finalExpBN254.zkasm +2095 -0
- package/main/pairings/halfPairingBN254.zkasm +428 -0
- package/main/pairings/loopLengthBN254.zkasm +75 -0
- package/main/pairings/millerLoopBN254.zkasm +741 -0
- package/main/pairings/pairingBN254.zkasm +481 -0
- package/main/pairings/unused/addFp12BN254.zkasm +130 -0
- package/main/pairings/unused/expByXCycloFp12BN254.zkasm +411 -0
- package/main/pairings/unused/expFp12BN254.zkasm +333 -0
- package/main/pairings/unused/subFp12BN254.zkasm +130 -0
- package/main/pairings/unused/xPseudoBinDecompBN254.zkasm +68 -0
- package/main/pairings/utilsTests/expCycloFp12BN254.zkasm +334 -0
- package/main/precompiled/end.zkasm +42 -0
- package/main/precompiled/identity.zkasm +99 -0
- package/main/precompiled/pre-ecAdd.zkasm +84 -0
- package/main/precompiled/pre-ecMul.zkasm +82 -0
- package/main/precompiled/pre-ecPairing.zkasm +72 -0
- package/main/precompiled/pre-ecrecover.zkasm +71 -0
- package/main/precompiled/pre-modexp.zkasm +367 -0
- package/main/precompiled/pre-sha2-256.zkasm +125 -0
- package/main/precompiled/revert-precompiled.zkasm +25 -0
- package/main/precompiled/selector.zkasm +77 -0
- package/main/process-change-l2-block.zkasm +147 -0
- package/main/process-tx.zkasm +587 -0
- package/main/tables/2-exp.zkasm +260 -0
- package/main/touched.zkasm +118 -0
- package/main/utils.zkasm +2335 -0
- package/main/vars.zkasm +117 -0
- package/package.json +62 -3
- package/test/bytes-length.zkasm +39 -0
- package/test/ecrecover.zkasm +538 -0
- package/test/lt4-test.zkasm +38 -0
- package/test/mstorex.zkasm +191 -0
- package/test/opcalldatacopy.ignore.zkasm +331 -0
- package/test/performance/read-push.zkasm +71 -0
- package/test/read-push.zkasm +304 -0
- package/test/testArrayArith.zkasm +1099 -0
- package/test/testArrayUtils.zkasm +335 -0
- package/test/testCycloFp12ArithBN254.zkasm +548 -0
- package/test/testEcAdd.zkasm +252 -0
- package/test/testEcMul.zkasm +231 -0
- package/test/testEcPairing.zkasm +436 -0
- package/test/testFinalExpBn254.zkasm +139 -0
- package/test/testFp12ArithBN254.zkasm +692 -0
- package/test/testFp2ArithBN254.zkasm +185 -0
- package/test/testFp4ArithBN254.zkasm +128 -0
- package/test/testFp6ArithBN254.zkasm +260 -0
- package/test/testFpArithBN254.zkasm +159 -0
- package/test/testFrArithBN254.zkasm +113 -0
- package/test/testHalfPairingBN254.zkasm +285 -0
- package/test/testModExp.zkasm +586 -0
- package/test/testModExpReturn.zkasm +81 -0
- package/test/testPairingBN254.zkasm +463 -0
- package/test/testPointArithBN254.zkasm +270 -0
- package/test/testSHA256.zkasm +27 -0
- package/test/touched-assert.zkasm +59 -0
- package/test/utils-expAD.zkasm +48 -0
- package/test/utils-getLenBytes.zkasm +36 -0
- package/tools/audit-tools/registry-op-checker.js +71 -0
- package/tools/get-not-used-labels.js +31 -0
- package/tools/helpers/helpers.js +47 -0
- package/tools/modexp-utils/README.md +5 -0
- package/tools/modexp-utils/modexp-test-gen.js +168 -0
- package/tools/modexp-utils/modexp-test-int.sage +37 -0
- package/tools/parallel-testing/checker.sh +6 -0
- package/tools/parallel-testing/gen-parallel-tests.js +78 -0
- package/tools/parallel-testing/parallel-tests-sample/sample.test.js +136 -0
- package/tools/run-tests-zkasm.js +83 -0
@@ -0,0 +1,587 @@
|
|
1
|
+
INCLUDE "map-opcodes.zkasm"
|
2
|
+
INCLUDE "precompiled/selector.zkasm"
|
3
|
+
INCLUDE "ecrecover/ecrecover.zkasm"
|
4
|
+
INCLUDE "touched.zkasm"
|
5
|
+
INCLUDE "tables/2-exp.zkasm"
|
6
|
+
|
7
|
+
; Blocks process txs
|
8
|
+
; A - Verify ecdsa signature
|
9
|
+
; B - Verify tx.sender does not have any code deployed (EIP3607)
|
10
|
+
; C - Verify chainID
|
11
|
+
; D - Verify and increase nonce
|
12
|
+
; E - Verify upfront cost
|
13
|
+
; F - Check transaction type
|
14
|
+
; F.1 - call contract
|
15
|
+
; F.2 - deploy contract
|
16
|
+
; G - Handle Gas
|
17
|
+
|
18
|
+
processTx:
|
19
|
+
;;;;;;;;;;;;;;;;;;
|
20
|
+
;; A - Verify ecdsa signature
|
21
|
+
;;;;;;;;;;;;;;;;;;
|
22
|
+
|
23
|
+
$${eventLog(onProcessTx)}
|
24
|
+
|
25
|
+
;;;;;;;;;
|
26
|
+
;; Store init state
|
27
|
+
;;;;;;;;;
|
28
|
+
|
29
|
+
SR :MSTORE(initSR)
|
30
|
+
CTX :MSTORE(currentCTX)
|
31
|
+
|
32
|
+
; Minimum of 100000 steps left to process a tx
|
33
|
+
%MAX_CNT_STEPS - STEP - 100000 :JMPN(outOfCountersStep)
|
34
|
+
%MAX_CNT_BINARY - CNT_BINARY - 100 :JMPN(outOfCountersBinary)
|
35
|
+
%MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith)
|
36
|
+
|
37
|
+
; Check the signature
|
38
|
+
$ => A :MLOAD(txSrcAddr)
|
39
|
+
A :MSTORE(txSrcOriginAddr)
|
40
|
+
$ :MLOAD(ecrecoverErrorCode), JMPNZ(invalidIntrinsicTxSignature)
|
41
|
+
|
42
|
+
;;;;;;;;;;;;;;;;;;
|
43
|
+
;; B - Verify tx.sender does not have any code deployed (EIP3607)
|
44
|
+
;;;;;;;;;;;;;;;;;;
|
45
|
+
|
46
|
+
%SMT_KEY_SC_LENGTH => B
|
47
|
+
0 => C
|
48
|
+
$ => B :SLOAD, JMPNZ(invalidIntrinsicTxSenderCode)
|
49
|
+
|
50
|
+
;;;;;;;;;;;;;;;;;;
|
51
|
+
;; C - Verify chainID
|
52
|
+
;;;;;;;;;;;;;;;;;;
|
53
|
+
|
54
|
+
; Don't check chainId for legacy transactions
|
55
|
+
$ => A :MLOAD(isPreEIP155), JMPNZ(endCheckChainId)
|
56
|
+
$ => A :MLOAD(txChainId)
|
57
|
+
$ => B :MLOAD(chainID) ; A: chainId tx
|
58
|
+
$ :EQ,JMPC(endCheckChainId, invalidIntrinsicTxChainId) ; If A == B --> endCheckChainId
|
59
|
+
endCheckChainId:
|
60
|
+
|
61
|
+
;; Reset warm/cold information
|
62
|
+
$ => A :MLOAD(txSrcOriginAddr), CALL(initTouchedTree)
|
63
|
+
:CALL(isColdAddress) ; add tx.origin to touched addresses
|
64
|
+
|
65
|
+
; Set tx status to success by default
|
66
|
+
1 :MSTORE(txStatus),CALL(checkpointBlockInfoTree)
|
67
|
+
;; Set gasPrice global var depending on effectivePercentage [0-255] -> txGasPrice = Floor((gasPrice * (effectivePercentage + 1)) / 256)
|
68
|
+
; gasPrice => A
|
69
|
+
$ => A :MLOAD(txGasPriceRLP)
|
70
|
+
; effectivePercentage => B
|
71
|
+
$ => B :MLOAD(effectivePercentageRLP)
|
72
|
+
; B -> [1, 256]
|
73
|
+
B + 1 => B
|
74
|
+
; A*B + C = D * 2**256 + op(E)
|
75
|
+
0 => C
|
76
|
+
; _effGasPriceShifted = gasPrice * (effectivePercentage + 1)
|
77
|
+
$${var _effGasPriceShifted = A * B}
|
78
|
+
; get value above 256 bits
|
79
|
+
${_effGasPriceShifted >> 256} => D
|
80
|
+
; compute ARITH
|
81
|
+
${_effGasPriceShifted} => E :ARITH
|
82
|
+
|
83
|
+
; txGasPrice = _effGasPriceShifted / 256
|
84
|
+
256 => B
|
85
|
+
; (_effGasPriceShifted / 256)(A) * 256(B) + (_effGasPriceShifted % 256)(C) = D * 2**256 + op(E)
|
86
|
+
${_effGasPriceShifted / 256} => A :MSTORE(txGasPrice)
|
87
|
+
${_effGasPriceShifted % 256} => C
|
88
|
+
; compute ARITH
|
89
|
+
E :ARITH
|
90
|
+
; check divisor > remainder
|
91
|
+
C => A
|
92
|
+
1 :LT
|
93
|
+
|
94
|
+
;;;;;;;;;;;;;;;;;;
|
95
|
+
;; D - Verify and increase nonce
|
96
|
+
;;;;;;;;;;;;;;;;;;
|
97
|
+
|
98
|
+
$ => A, E :MLOAD(txSrcOriginAddr) ; Address of the origin to A and E
|
99
|
+
%SMT_KEY_NONCE => B
|
100
|
+
0 => C
|
101
|
+
$ => A :SLOAD
|
102
|
+
$ => B :MLOAD(txNonce)
|
103
|
+
$ => C :EQ, JMPNC(invalidIntrinsicTxNonce) ; Compare nonce state tree with nonce transaction
|
104
|
+
; increase nonce by 1
|
105
|
+
1 => B
|
106
|
+
$ => D :ADD ; compute [nonce + 1 => D]
|
107
|
+
E => A
|
108
|
+
%SMT_KEY_NONCE => B
|
109
|
+
0 => C
|
110
|
+
$ => SR :SSTORE ; Store the nonce plus one
|
111
|
+
|
112
|
+
;;;;;;;;;;;;;;;;;;
|
113
|
+
;; E - Verify upfront cost
|
114
|
+
;;;;;;;;;;;;;;;;;;
|
115
|
+
|
116
|
+
; Verify batch gas limit
|
117
|
+
$ => B :MLOAD(txGasLimit)
|
118
|
+
; Check batch gas limit is not exceeded by transaction
|
119
|
+
%TX_GAS_LIMIT => A
|
120
|
+
$ :LT,JMPC(invalidIntrinsicBatchGasLimit)
|
121
|
+
|
122
|
+
; Intrinsic gas --> gas Limit >= 21000 + calldata cost + deployment cost
|
123
|
+
%BASE_TX_GAS => E ; Store init intrinsic gas at E
|
124
|
+
$ => A :MLOAD(isCreateContract), JMPNZ(addDeploymentGasCost, getCalldataGasCost)
|
125
|
+
|
126
|
+
addDeploymentGasCost:
|
127
|
+
%BASE_TX_DEPLOY_GAS => E ; 53000 gas if transaction is a create
|
128
|
+
|
129
|
+
getCalldataGasCost:
|
130
|
+
$ => A :MLOAD(txCalldataLen)
|
131
|
+
0 => B
|
132
|
+
$ :EQ,JMPC(endCalldataIntrinsicGas)
|
133
|
+
|
134
|
+
addGas:
|
135
|
+
$ => HASHPOS :MLOAD(dataStarts)
|
136
|
+
0 => C :JMP(loopBytes)
|
137
|
+
|
138
|
+
loopBytes:
|
139
|
+
%MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep)
|
140
|
+
A - C - 1 :JMPN(endCalldataIntrinsicGas)
|
141
|
+
E => B
|
142
|
+
$ => E :MLOAD(batchHashDataId)
|
143
|
+
$ => D :HASHK1(E)
|
144
|
+
B => E
|
145
|
+
C + 1 => C
|
146
|
+
D - 1 :JMPN(add4Gas, add16Gas)
|
147
|
+
|
148
|
+
add4Gas:
|
149
|
+
E + 4 => E :JMP(loopBytes)
|
150
|
+
|
151
|
+
add16Gas:
|
152
|
+
E + 16 => E :JMP(loopBytes)
|
153
|
+
|
154
|
+
endCalldataIntrinsicGas:
|
155
|
+
; Compare gas limit >= intrinsic gas
|
156
|
+
$ => A :MLOAD(txGasLimit)
|
157
|
+
E => B
|
158
|
+
$ :LT, JMPC(invalidIntrinsicTxGasLimit)
|
159
|
+
; Store calculated gas for later usage
|
160
|
+
E :MSTORE(gasCalldata)
|
161
|
+
|
162
|
+
; Check upfront cost: balance >= gas price * gas limit + value
|
163
|
+
; gas price * gas limit
|
164
|
+
$ => B :MLOAD(txGasPrice)
|
165
|
+
A :MSTORE(arithA)
|
166
|
+
B :MSTORE(arithB), CALL(mulARITH)
|
167
|
+
$ :MLOAD(mulArithOverflowFlag), JMPNZ(invalidIntrinsicTxGasOverflow)
|
168
|
+
$ => D :MLOAD(arithRes1)
|
169
|
+
; Get caller balance
|
170
|
+
$ => A :MLOAD(txSrcOriginAddr)
|
171
|
+
0 => B, C
|
172
|
+
$ => C :SLOAD
|
173
|
+
; (gas price * gas limit) + value
|
174
|
+
$ => B :MLOAD(txValue)
|
175
|
+
D :MSTORE(arithA)
|
176
|
+
B :MSTORE(arithB), CALL(addARITH)
|
177
|
+
$ :MLOAD(addArithOverflow), JMPNZ(invalidIntrinsicTxBalance)
|
178
|
+
$ => B :MLOAD(arithRes1)
|
179
|
+
; Comparison
|
180
|
+
C => A
|
181
|
+
$ :LT, JMPC(invalidIntrinsicTxBalance)
|
182
|
+
|
183
|
+
; Subtract (gas price * gas limit) from caller balance
|
184
|
+
C :MSTORE(arithA)
|
185
|
+
D :MSTORE(arithB), CALL(subARITH)
|
186
|
+
; Subtracted balance result in D
|
187
|
+
$ => D :MLOAD(arithRes1)
|
188
|
+
$ => A :MLOAD(txSrcOriginAddr)
|
189
|
+
0 => B,C
|
190
|
+
$ => SR :SSTORE
|
191
|
+
|
192
|
+
; Store state root with upfront cost subtracted and nonce increased
|
193
|
+
SR :MSTORE(initSR)
|
194
|
+
|
195
|
+
; Substract intrinsic gas
|
196
|
+
$ => GAS :MLOAD(txGasLimit)
|
197
|
+
$ => A :MLOAD(gasCalldata)
|
198
|
+
GAS - A => GAS
|
199
|
+
|
200
|
+
;;;;;;;;;;;;;;;;;;
|
201
|
+
;; F - Check transaction type
|
202
|
+
;;;;;;;;;;;;;;;;;;
|
203
|
+
txType:
|
204
|
+
|
205
|
+
; Compute deployment address if create contract operation
|
206
|
+
$ => A :MLOAD(isCreateContract), JMPNZ(getContractAddress)
|
207
|
+
$ => A :MLOAD(txDestAddr)
|
208
|
+
:CALL(isColdAddress) ; Add 'to' to touched addresses
|
209
|
+
; Check 'to' is zero or precompiled contract
|
210
|
+
; Check zero address since zero address is not a precompiled contract
|
211
|
+
0 => B
|
212
|
+
$ :EQ, JMPC(callContract)
|
213
|
+
10 => B
|
214
|
+
$ :LT,JMPC(selectorPrecompiled, callContract)
|
215
|
+
|
216
|
+
;;;;;;;;;;;;;;;;;;
|
217
|
+
;; F.2 - Deploy contract
|
218
|
+
;; - Compute new contract address
|
219
|
+
;; - Process bytecode
|
220
|
+
;; - End deploy: add state-tree hash bytecode and bytecode length
|
221
|
+
;;;;;;;;;;;;;;;;;;
|
222
|
+
|
223
|
+
;; compute new create address
|
224
|
+
getContractAddress:
|
225
|
+
; A new hash with position 0 is started
|
226
|
+
0 => HASHPOS
|
227
|
+
; We get a new hashId
|
228
|
+
$ => E :MLOAD(lastHashKIdUsed)
|
229
|
+
E+1 => E :MSTORE(lastHashKIdUsed)
|
230
|
+
; Check if create is with CREATE2 opcode
|
231
|
+
$ => A :MLOAD(isCreate2), JMPNZ(create2)
|
232
|
+
; Check keccak counters
|
233
|
+
$ => A :MLOAD(cntKeccakPreProcess)
|
234
|
+
%MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1:JMPN(outOfCountersKeccak)
|
235
|
+
$ => A :MLOAD(txNonce)
|
236
|
+
0x80 => B
|
237
|
+
$ :LT,JMPC(nonce1byte)
|
238
|
+
$ => C :MLOAD(lengthNonce)
|
239
|
+
; 1 byte length address + 20 bytes address + 1 byte length nonce + C bytes nonce
|
240
|
+
; RLPlist[RLP(address):RLP(nonce)] --> 1 byte length address + 20 bytes address + 1 byte length nonce + C bytes nonce
|
241
|
+
; --> 0xc0 + address RLP bytes(1 + 20) + nonce RLP bytes (variable)
|
242
|
+
; RLP(address) --> 20 bytes header + address value --> 0x94 + address value
|
243
|
+
; RLP(nonce) --> nonce < 128 --> 1 byte --> value itself
|
244
|
+
; --> nonce > 128 --> (1 byte + length nonce) + value itself
|
245
|
+
0xc0 + 22 + C :HASHK1(E)
|
246
|
+
0x94 :HASHK1(E)
|
247
|
+
20 => D
|
248
|
+
$ => B :MLOAD(txSrcAddr)
|
249
|
+
B :HASHK(E)
|
250
|
+
0x80 + C :HASHK1(E)
|
251
|
+
C => D
|
252
|
+
A :HASHK(E), JMP(endContractAddress)
|
253
|
+
|
254
|
+
nonce1byte:
|
255
|
+
$ => A :MLOAD(txSrcAddr)
|
256
|
+
$ => B :MLOAD(txNonce)
|
257
|
+
0xc0 + 22 :HASHK1(E)
|
258
|
+
0x94 :HASHK1(E)
|
259
|
+
20 => D
|
260
|
+
A :HASHK(E)
|
261
|
+
B :JMPZ(nonceIs0)
|
262
|
+
B :HASHK1(E),JMP(endContractAddress)
|
263
|
+
|
264
|
+
nonceIs0:
|
265
|
+
0x80 :HASHK1(E),JMP(endContractAddress)
|
266
|
+
|
267
|
+
;; compute new contract address as CREATE2 spec: keccak256(0xff ++ address ++ salt ++ keccak256(init_code))[12:] (https://eips.ethereum.org/EIPS/eip-1014)
|
268
|
+
create2:
|
269
|
+
$ => C :MLOAD(txCalldataLen) ; less than 2**32 bytes. Enforced by memory expansion gas cost & smart contract batchL2DataHash
|
270
|
+
; Check keccak counters
|
271
|
+
C + 1 :MSTORE(arithA)
|
272
|
+
136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
273
|
+
$ => B :MLOAD(arithRes1)
|
274
|
+
$ => A :MLOAD(cntKeccakPreProcess)
|
275
|
+
; -2 because we will use one more keccak for generating contract address
|
276
|
+
%MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 2 - B :JMPN(outOfCountersKeccak)
|
277
|
+
|
278
|
+
$ => CTX :MLOAD(originCTX)
|
279
|
+
$ => B :MLOAD(argsOffsetCall)
|
280
|
+
|
281
|
+
loopCreate2:
|
282
|
+
; check zk-counters
|
283
|
+
%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep)
|
284
|
+
|
285
|
+
C :JMPZ(create2end)
|
286
|
+
C - 32 :JMPN(endloopCreate2)
|
287
|
+
B => E :CALL(MLOAD32)
|
288
|
+
E => B
|
289
|
+
32 => D
|
290
|
+
$ => E :MLOAD(lastHashKIdUsed)
|
291
|
+
A :HASHK(E)
|
292
|
+
C - 32 => C :JMP(loopCreate2)
|
293
|
+
|
294
|
+
endloopCreate2:
|
295
|
+
B => E :CALL(MLOADX)
|
296
|
+
32 - C => D :CALL(SHRarith)
|
297
|
+
C => D
|
298
|
+
$ => E :MLOAD(lastHashKIdUsed)
|
299
|
+
A :HASHK(E)
|
300
|
+
|
301
|
+
create2end:
|
302
|
+
$ => CTX :MLOAD(currentCTX)
|
303
|
+
HASHPOS :HASHKLEN(E)
|
304
|
+
$ => C :HASHKDIGEST(E)
|
305
|
+
|
306
|
+
; new hash with position 0 is started
|
307
|
+
0 => HASHPOS
|
308
|
+
$ => E :MLOAD(lastHashKIdUsed)
|
309
|
+
E+1 => E :MSTORE(lastHashKIdUsed)
|
310
|
+
0xff :HASHK1(E)
|
311
|
+
20 => D
|
312
|
+
$ => A :MLOAD(txSrcAddr)
|
313
|
+
A :HASHK(E)
|
314
|
+
32 => D
|
315
|
+
$ => B :MLOAD(salt)
|
316
|
+
B :HASHK(E)
|
317
|
+
32 => D
|
318
|
+
C :HASHK(E)
|
319
|
+
|
320
|
+
endContractAddress:
|
321
|
+
HASHPOS :HASHKLEN(E)
|
322
|
+
$ => A :HASHKDIGEST(E), CALL(maskAddress) ; Mask address to 20 bytes
|
323
|
+
A :MSTORE(createContractAddress)
|
324
|
+
A :MSTORE(txDestAddr)
|
325
|
+
A :MSTORE(storageAddr)
|
326
|
+
|
327
|
+
;; deploy contract in state-tree
|
328
|
+
deploy:
|
329
|
+
%MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep)
|
330
|
+
%MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon)
|
331
|
+
%MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary)
|
332
|
+
:CALL(isColdAddress) ; add address to touched addresses
|
333
|
+
; check if address is deployable ( nonce == bytecode == 0)
|
334
|
+
A => E
|
335
|
+
|
336
|
+
; read nonce
|
337
|
+
0 => C
|
338
|
+
%SMT_KEY_NONCE => B
|
339
|
+
$ => B :SLOAD
|
340
|
+
0 => A
|
341
|
+
$ :LT,JMPC(deployAddressCollision)
|
342
|
+
|
343
|
+
; read bytecode
|
344
|
+
E => A
|
345
|
+
%SMT_KEY_SC_CODE => B
|
346
|
+
$ => B :SLOAD
|
347
|
+
0 => A
|
348
|
+
$ :LT,JMPC(deployAddressCollision)
|
349
|
+
|
350
|
+
; set contract nonce to 1
|
351
|
+
E => A
|
352
|
+
1 => D
|
353
|
+
%SMT_KEY_NONCE => B
|
354
|
+
$ => SR :SSTORE
|
355
|
+
; Move balances if value > 0 just before deploy
|
356
|
+
$ => B :MLOAD(txValue)
|
357
|
+
0 => A
|
358
|
+
zkPC+2 => RR
|
359
|
+
$ :LT, JMPC(moveBalances)
|
360
|
+
0 => PC
|
361
|
+
0 => SP :JMP(readCode)
|
362
|
+
|
363
|
+
;; read calldata bytes of a deploy transaction and process them
|
364
|
+
readDeployBytecode:
|
365
|
+
; check transaction is a deploy transaction
|
366
|
+
$ => B :MLOAD(isCreate), JMPNZ(readDeployBytecodeCreate)
|
367
|
+
; check enough bytes to read in calldata
|
368
|
+
$ => B :MLOAD(txCalldataLen)
|
369
|
+
B - PC - 1 :JMPN(defaultOpCode)
|
370
|
+
$ => HASHPOS :MLOAD(dataStarts)
|
371
|
+
HASHPOS + PC => HASHPOS
|
372
|
+
$ => E :MLOAD(batchHashDataId)
|
373
|
+
$ => RR :HASHK1(E)
|
374
|
+
$${eventLog(onOpcode(RR))}
|
375
|
+
PC + 1 => PC :JMP(@mapping_opcodes + RR)
|
376
|
+
|
377
|
+
;; read calldata bytes of a CREATE/CREATE2 call and process them
|
378
|
+
readDeployBytecodeCreate:
|
379
|
+
$ => E :MLOAD(txCalldataLen)
|
380
|
+
$ => CTX :MLOAD(originCTX)
|
381
|
+
; check enough bytes to read in memory
|
382
|
+
E - PC - 1 :JMPN(readDeployBytecodeCreateDefault)
|
383
|
+
$ => E :MLOAD(argsOffsetCall)
|
384
|
+
E + PC => E
|
385
|
+
1 => C :CALL(MLOADX)
|
386
|
+
$ => CTX :MLOAD(currentCTX)
|
387
|
+
31 => D :CALL(SHRarith)
|
388
|
+
A => RR
|
389
|
+
$${eventLog(onOpcode(RR))}
|
390
|
+
PC + 1 => PC :JMP(@mapping_opcodes + RR)
|
391
|
+
|
392
|
+
;; handle error no more bytecode to read when call CREATE/CREATE2
|
393
|
+
readDeployBytecodeCreateDefault:
|
394
|
+
$ => CTX :MLOAD(currentCTX), JMP(defaultOpCode)
|
395
|
+
|
396
|
+
;;;;;;;;;;;;;;;;;;
|
397
|
+
;; F.1 - Call contract
|
398
|
+
;; - Load bytecode from its state-tree hash
|
399
|
+
;; - Process bytecode
|
400
|
+
;; - End deploy: add state-tree hash bytecode and bytecode length
|
401
|
+
;;;;;;;;;;;;;;;;;;
|
402
|
+
callContract:
|
403
|
+
; Move balances if value > 0 just before executing the contract CALL
|
404
|
+
$ => B :MLOAD(txValue)
|
405
|
+
0 => A
|
406
|
+
zkPC+2 => RR
|
407
|
+
$ :LT, JMPC(moveBalances)
|
408
|
+
0 => PC
|
409
|
+
0 => SP
|
410
|
+
|
411
|
+
$ => A :MLOAD(txDestAddr)
|
412
|
+
|
413
|
+
; get contract length
|
414
|
+
%SMT_KEY_SC_LENGTH => B
|
415
|
+
0 => C
|
416
|
+
$ => B :SLOAD
|
417
|
+
B :MSTORE(bytecodeLength)
|
418
|
+
0 => A
|
419
|
+
$ :EQ, JMPC(defaultOpCode) ;no bytecode
|
420
|
+
|
421
|
+
; check poseidon counters
|
422
|
+
; 56 is the value used by the prover to increment poseidon counters depending on the hash length
|
423
|
+
B :MSTORE(arithA)
|
424
|
+
56 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
425
|
+
$ => B :MLOAD(arithRes1)
|
426
|
+
%MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 1 - B :JMPN(outOfCountersPoseidon)
|
427
|
+
%MAX_CNT_PADDING_PG - CNT_PADDING_PG - 1 - B :JMPN(outOfCountersPadding)
|
428
|
+
|
429
|
+
; get hash contract
|
430
|
+
$ => A :MLOAD(txDestAddr)
|
431
|
+
%SMT_KEY_SC_CODE => B
|
432
|
+
$ => A :SLOAD
|
433
|
+
|
434
|
+
; get a new hashPId
|
435
|
+
$ => E :MLOAD(nextHashPId)
|
436
|
+
E :MSTORE(contractHashId)
|
437
|
+
E+1 :MSTORE(nextHashPId)
|
438
|
+
|
439
|
+
; load contract bytecode
|
440
|
+
A :HASHPDIGEST(E)
|
441
|
+
|
442
|
+
readByteCode:
|
443
|
+
$ => E :MLOAD(contractHashId) ; hash index
|
444
|
+
$ => A :MLOAD(txDestAddr)
|
445
|
+
; check next byte exist on the bytecode
|
446
|
+
$ => B :MLOAD(bytecodeLength)
|
447
|
+
B - PC - 1 :JMPN(defaultOpCode) ; no bytecode treated as 0x00
|
448
|
+
PC => HASHPOS
|
449
|
+
$ => RR :HASHP1(E)
|
450
|
+
$${eventLog(onOpcode(RR))}
|
451
|
+
PC + 1 => PC :JMP(@mapping_opcodes + RR)
|
452
|
+
|
453
|
+
readCode:
|
454
|
+
%MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep)
|
455
|
+
$ => A :MLOAD(isCreateContract), JMPNZ(readDeployBytecode, readByteCode)
|
456
|
+
|
457
|
+
;; Compute and save hash bytecode and bytecode length in the state-tree
|
458
|
+
endDeploy:
|
459
|
+
; checks zk-counters
|
460
|
+
%MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep)
|
461
|
+
%MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon)
|
462
|
+
%MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary)
|
463
|
+
; called from `opRETURNDeploy` which has: C --> length, E --> offset
|
464
|
+
; only when first context ends on deploy
|
465
|
+
; If length is 0 do not modify state-tree
|
466
|
+
C :JMPZ(handleGas)
|
467
|
+
|
468
|
+
; save offset memory and length to compute hash bytecode. Read bytecode first byte
|
469
|
+
E :MSTORE(memOffsetLinearPoseidon)
|
470
|
+
C :MSTORE(memSizeLinearPoseidon), CALL(checkBytecodeStartsEF) ; in: [memOffset], out: [startsWithEFn]
|
471
|
+
|
472
|
+
; check bytecode first byte != 0xEF
|
473
|
+
$ :MLOAD(startsWithEF), JMPNZ(invalidCodeStartsEF)
|
474
|
+
|
475
|
+
; set bytecode length
|
476
|
+
$ => A :MLOAD(createContractAddress)
|
477
|
+
%SMT_KEY_SC_LENGTH => B
|
478
|
+
C => D
|
479
|
+
0 => C
|
480
|
+
$ => SR :SSTORE
|
481
|
+
A :MSTORE(txDestAddr), CALL(hashPoseidonLinearFromMemory)
|
482
|
+
$ => A :MLOAD(createContractAddress)
|
483
|
+
0 => C
|
484
|
+
%SMT_KEY_SC_CODE => B
|
485
|
+
$ => SR :SSTORE, JMP(handleGas)
|
486
|
+
|
487
|
+
;;;;;;;;;;;;;;;;;;
|
488
|
+
;; G - Handle GAS
|
489
|
+
;; - Check refund gas
|
490
|
+
;; - Return gas not used to caller
|
491
|
+
;; - Pay gas to sequencer
|
492
|
+
;;;;;;;;;;;;;;;;;;
|
493
|
+
handleGasFromError:
|
494
|
+
; Set tx status to failure
|
495
|
+
0 :MSTORE(txStatus)
|
496
|
+
;; compute maximum gas to refund
|
497
|
+
handleGas:
|
498
|
+
%MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep)
|
499
|
+
%MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*4 :JMPN(outOfCountersPoseidon)
|
500
|
+
%MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary)
|
501
|
+
0 => A
|
502
|
+
$ => B :MLOAD(gasRefund), JMPZ(refundGas)
|
503
|
+
$ => A :MLOAD(txGasLimit)
|
504
|
+
A - GAS => A
|
505
|
+
; Div operation with Arith
|
506
|
+
A :MSTORE(arithA)
|
507
|
+
2 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
508
|
+
$ => A :MLOAD(arithRes1)
|
509
|
+
A - B :JMPN(refundGas)
|
510
|
+
B => A
|
511
|
+
|
512
|
+
;; add remaining gas to transaction origin
|
513
|
+
refundGas:
|
514
|
+
GAS + A => GAS
|
515
|
+
GAS => A
|
516
|
+
$ => B :MLOAD(txGasPrice)
|
517
|
+
;Mul operation with Arith
|
518
|
+
A :MSTORE(arithA)
|
519
|
+
B :MSTORE(arithB), CALL(mulARITH)
|
520
|
+
$ => D :MLOAD(arithRes1)
|
521
|
+
|
522
|
+
$ => A :MLOAD(txSrcOriginAddr)
|
523
|
+
0 => B,C ; balance key smt
|
524
|
+
$ => A :SLOAD ; Original Balance in A
|
525
|
+
|
526
|
+
; Add operation with Arith
|
527
|
+
A :MSTORE(arithA)
|
528
|
+
D :MSTORE(arithB), CALL(addARITH)
|
529
|
+
$ => D :MLOAD(arithRes1)
|
530
|
+
|
531
|
+
$ => A :MLOAD(txSrcOriginAddr)
|
532
|
+
0 => B,C ; balance key smt
|
533
|
+
$ => SR :SSTORE
|
534
|
+
|
535
|
+
|
536
|
+
;; Send gas spent to sequencer
|
537
|
+
sendGasSeq:
|
538
|
+
$ => A :MLOAD(txGasLimit)
|
539
|
+
A - GAS => A
|
540
|
+
|
541
|
+
$ => B :MLOAD(txGasPrice)
|
542
|
+
; Mul operation with Arith
|
543
|
+
A :MSTORE(arithA)
|
544
|
+
B :MSTORE(arithB), CALL(mulARITH)
|
545
|
+
$ => D :MLOAD(arithRes1) ; value to pay the sequencer in D
|
546
|
+
|
547
|
+
$ => A :MLOAD(sequencerAddr)
|
548
|
+
0 => B,C ; Balance key smt
|
549
|
+
$ => A :SLOAD ; Original Balance in A
|
550
|
+
; Add operation with Arith
|
551
|
+
A :MSTORE(arithA)
|
552
|
+
D :MSTORE(arithB), CALL(addARITH)
|
553
|
+
$ => D :MLOAD(arithRes1)
|
554
|
+
$ => A :MLOAD(sequencerAddr)
|
555
|
+
0 => B,C ; balance key smt
|
556
|
+
$ => SR :SSTORE, JMP(processTxFinished)
|
557
|
+
|
558
|
+
;; handle invalid transaction due to intrinsic checks
|
559
|
+
invalidIntrinsicTxSignature:
|
560
|
+
$${eventLog(onError, intrinsic_invalid_signature)} :JMP(handleIntrinsicError)
|
561
|
+
|
562
|
+
invalidIntrinsicTxChainId:
|
563
|
+
$${eventLog(onError, intrinsic_invalid_chain_id)} :JMP(handleIntrinsicError)
|
564
|
+
|
565
|
+
invalidIntrinsicTxNonce:
|
566
|
+
$${eventLog(onError, intrinsic_invalid_nonce)} :JMP(handleIntrinsicError)
|
567
|
+
|
568
|
+
invalidIntrinsicTxGasLimit:
|
569
|
+
$${eventLog(onError, intrinsic_invalid_gas_limit)} :JMP(handleIntrinsicError)
|
570
|
+
|
571
|
+
invalidIntrinsicTxGasOverflow:
|
572
|
+
$${eventLog(onError, intrinsic_invalid_gas_overflow)} :JMP(handleIntrinsicError)
|
573
|
+
|
574
|
+
invalidIntrinsicTxBalance:
|
575
|
+
$${eventLog(onError, intrinsic_invalid_balance)} :JMP(handleIntrinsicError)
|
576
|
+
|
577
|
+
invalidIntrinsicBatchGasLimit:
|
578
|
+
$${eventLog(onError, intrinsic_invalid_batch_gas_limit)}:JMP(handleIntrinsicError)
|
579
|
+
|
580
|
+
invalidIntrinsicTxSenderCode:
|
581
|
+
$${eventLog(onError, intrinsic_invalid_sender_code)} :JMP(handleIntrinsicError)
|
582
|
+
handleIntrinsicError:
|
583
|
+
$ => SR :MLOAD(originSR), JMP(processIntrinsicTxFinished)
|
584
|
+
|
585
|
+
;; handle error no more bytecode to read
|
586
|
+
defaultOpCode:
|
587
|
+
$${eventLog(onOpcode(0))} :JMP(opSTOP)
|