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 zkevm-rom might be problematic. Click here for more details.

Files changed (232) hide show
  1. package/.eslintrc.js +33 -0
  2. package/.github/CODEOWNERS +14 -0
  3. package/.github/ISSUE_TEMPLATE/bug.yml +38 -0
  4. package/.github/ISSUE_TEMPLATE/feature.yml +26 -0
  5. package/.github/ISSUE_TEMPLATE/question.yml +26 -0
  6. package/.github/workflows/main.yaml +40 -0
  7. package/LICENSE +636 -0
  8. package/README.md +23 -5
  9. package/audits/Hexens_Polygon_zkEVM_PUBLIC_27.02.23.pdf +0 -0
  10. package/audits/Polygon-zkEVM-Public-v1.1-verichains-19-03-2024.pdf +0 -0
  11. package/audits/zkEVM-ROM-upgrade-1-Spearbit-30-May.pdf +0 -0
  12. package/audits/zkEVM-ROM-upgrade-2-Spearbit-21-August.pdf +0 -0
  13. package/audits/zkEVM-engagement-1-Spearbit-27-March.pdf +0 -0
  14. package/audits/zkEVM-engagement-2-Spearbit-27-March.pdf +0 -0
  15. package/audits/zkEVM-engagement-3-Spearbit-6-April.pdf +0 -0
  16. package/counters/README.md +45 -0
  17. package/counters/counters-executor.js +80 -0
  18. package/counters/countersConstants.zkasm +370 -0
  19. package/counters/endIncludes.zkasm +18 -0
  20. package/counters/initIncludes.zkasm +2 -0
  21. package/counters/tests/MLOAD32.zkasm +27 -0
  22. package/counters/tests/MLOADX.zkasm +30 -0
  23. package/counters/tests/MSTORE32.zkasm +32 -0
  24. package/counters/tests/MSTOREX.zkasm +36 -0
  25. package/counters/tests/SHLarith.zkasm +28 -0
  26. package/counters/tests/SHLarithBit.zkasm +28 -0
  27. package/counters/tests/SHRarith.zkasm +28 -0
  28. package/counters/tests/SHRarithBit.zkasm +28 -0
  29. package/counters/tests/abs.zkasm +29 -0
  30. package/counters/tests/addBatchHashByteByByte.zkasm +31 -0
  31. package/counters/tests/computeGasSendCall.zkasm +30 -0
  32. package/counters/tests/divArith.zkasm +27 -0
  33. package/counters/tests/expAD.zkasm +30 -0
  34. package/counters/tests/getLenBits.zkasm +30 -0
  35. package/counters/tests/getLenBytes.zkasm +32 -0
  36. package/counters/tests/isEmptyAccount.zkasm +30 -0
  37. package/counters/tests/mulARITH.zkasm +28 -0
  38. package/counters/tests/offsetUtil.zkasm +29 -0
  39. package/counters/tests/opADDMOD.zkasm +28 -0
  40. package/counters/tests/opAdd.zkasm +27 -0
  41. package/counters/tests/opBLOCKHASH.zkasm +28 -0
  42. package/counters/tests/opCALL.zkasm +41 -0
  43. package/counters/tests/opCALLCODE.zkasm +41 -0
  44. package/counters/tests/opCALLDATACOPY.zkasm +28 -0
  45. package/counters/tests/opCALLDATALOAD.zkasm +27 -0
  46. package/counters/tests/opCODECOPY.zkasm +28 -0
  47. package/counters/tests/opCREATE.zkasm +35 -0
  48. package/counters/tests/opCREATE2.zkasm +35 -0
  49. package/counters/tests/opDELEGATECALL.zkasm +35 -0
  50. package/counters/tests/opDIV.zkasm +27 -0
  51. package/counters/tests/opEXP.zkasm +29 -0
  52. package/counters/tests/opEXTCODECOPY.zkasm +29 -0
  53. package/counters/tests/opMOD.zkasm +27 -0
  54. package/counters/tests/opMUL.zkasm +27 -0
  55. package/counters/tests/opMULMOD.zkasm +28 -0
  56. package/counters/tests/opRETURN.zkasm +32 -0
  57. package/counters/tests/opRETURNDATACOPY.zkasm +29 -0
  58. package/counters/tests/opREVERT.zkasm +32 -0
  59. package/counters/tests/opSDIV.zkasm +28 -0
  60. package/counters/tests/opSHA3.zkasm +28 -0
  61. package/counters/tests/opSIGNEXTEND.zkasm +27 -0
  62. package/counters/tests/opSMOD.zkasm +28 -0
  63. package/counters/tests/opSTATICCALL.zkasm +35 -0
  64. package/counters/tests/opSUB.zkasm +27 -0
  65. package/counters/tests/saveMem.zkasm +31 -0
  66. package/docs/opcode-cost-zk-counters.md +315 -0
  67. package/docs/usage-ecrecover.md +51 -0
  68. package/index.js +43 -0
  69. package/main/block-info.zkasm +204 -0
  70. package/main/constants.zkasm +145 -0
  71. package/main/ecrecover/addFpEc.zkasm +31 -0
  72. package/main/ecrecover/checkSqrtFpEc.zkasm +1558 -0
  73. package/main/ecrecover/constEc.zkasm +13 -0
  74. package/main/ecrecover/ecrecover.zkasm +280 -0
  75. package/main/ecrecover/invFnEc.zkasm +44 -0
  76. package/main/ecrecover/invFpEc.zkasm +45 -0
  77. package/main/ecrecover/mulFnEc.zkasm +36 -0
  78. package/main/ecrecover/mulFpEc.zkasm +36 -0
  79. package/main/ecrecover/mulPointEc.zkasm +311 -0
  80. package/main/ecrecover/sqFpEc.zkasm +38 -0
  81. package/main/ecrecover/sqrtFpEc.zkasm +70 -0
  82. package/main/end.zkasm +4 -0
  83. package/main/l2-tx-hash.zkasm +159 -0
  84. package/main/load-change-l2-block-utils.zkasm +11 -0
  85. package/main/load-change-l2-block.zkasm +28 -0
  86. package/main/load-tx-rlp-utils.zkasm +72 -0
  87. package/main/load-tx-rlp.zkasm +431 -0
  88. package/main/main.zkasm +237 -0
  89. package/main/map-opcodes.zkasm +274 -0
  90. package/main/modexp/array_lib/array_add_AGTB.zkasm +123 -0
  91. package/main/modexp/array_lib/array_add_short.zkasm +85 -0
  92. package/main/modexp/array_lib/array_div.zkasm +215 -0
  93. package/main/modexp/array_lib/array_div_long.zkasm +284 -0
  94. package/main/modexp/array_lib/array_div_short.zkasm +222 -0
  95. package/main/modexp/array_lib/array_mul.zkasm +97 -0
  96. package/main/modexp/array_lib/array_mul_long.zkasm +156 -0
  97. package/main/modexp/array_lib/array_mul_short.zkasm +127 -0
  98. package/main/modexp/array_lib/array_square.zkasm +246 -0
  99. package/main/modexp/array_lib/unused/array_add.zkasm +100 -0
  100. package/main/modexp/array_lib/unused/array_is_odd.zkasm +23 -0
  101. package/main/modexp/array_lib/unused/array_is_one.zkasm +33 -0
  102. package/main/modexp/array_lib/unused/array_is_zero.zkasm +34 -0
  103. package/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +111 -0
  104. package/main/modexp/array_lib/unused/array_unshift.zkasm +37 -0
  105. package/main/modexp/array_lib/utils/array_compare.zkasm +82 -0
  106. package/main/modexp/array_lib/utils/array_trim.zkasm +49 -0
  107. package/main/modexp/constants.zkasm +5 -0
  108. package/main/modexp/modexp.zkasm +296 -0
  109. package/main/modexp/modexp_utils.zkasm +230 -0
  110. package/main/opcodes/arithmetic.zkasm +357 -0
  111. package/main/opcodes/block.zkasm +163 -0
  112. package/main/opcodes/calldata-returndata-code.zkasm +619 -0
  113. package/main/opcodes/comparison.zkasm +446 -0
  114. package/main/opcodes/context-information.zkasm +169 -0
  115. package/main/opcodes/create-terminate-context.zkasm +1011 -0
  116. package/main/opcodes/crypto.zkasm +96 -0
  117. package/main/opcodes/flow-control.zkasm +126 -0
  118. package/main/opcodes/logs.zkasm +193 -0
  119. package/main/opcodes/stack-operations.zkasm +658 -0
  120. package/main/opcodes/storage-memory.zkasm +313 -0
  121. package/main/pairings/BN254/addPointBN254.zkasm +245 -0
  122. package/main/pairings/BN254/ecAdd.zkasm +312 -0
  123. package/main/pairings/BN254/ecMul.zkasm +159 -0
  124. package/main/pairings/BN254/escalarMulBN254.zkasm +155 -0
  125. package/main/pairings/BN254/lineDiffPointsBN254.zkasm +83 -0
  126. package/main/pairings/BN254/lineSamePointsBN254.zkasm +96 -0
  127. package/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm +49 -0
  128. package/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +236 -0
  129. package/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +444 -0
  130. package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +212 -0
  131. package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +228 -0
  132. package/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm +64 -0
  133. package/main/pairings/FP12BN254/frob2Fp12BN254.zkasm +80 -0
  134. package/main/pairings/FP12BN254/frob3Fp12BN254.zkasm +96 -0
  135. package/main/pairings/FP12BN254/frobFp12BN254.zkasm +96 -0
  136. package/main/pairings/FP12BN254/inverseFp12BN254.zkasm +289 -0
  137. package/main/pairings/FP12BN254/mulFp12BN254.zkasm +408 -0
  138. package/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm +296 -0
  139. package/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm +291 -0
  140. package/main/pairings/FP12BN254/squareFp12BN254.zkasm +376 -0
  141. package/main/pairings/FP2BN254/addFp2BN254.zkasm +19 -0
  142. package/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm +20 -0
  143. package/main/pairings/FP2BN254/invFp2BN254.zkasm +66 -0
  144. package/main/pairings/FP2BN254/mulFp2BN254.zkasm +19 -0
  145. package/main/pairings/FP2BN254/squareFp2BN254.zkasm +21 -0
  146. package/main/pairings/FP2BN254/subFp2BN254.zkasm +19 -0
  147. package/main/pairings/FP4BN254/squareFp4BN254.zkasm +76 -0
  148. package/main/pairings/FP6BN254/addFp6BN254.zkasm +59 -0
  149. package/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm +51 -0
  150. package/main/pairings/FP6BN254/inverseFp6BN254.zkasm +208 -0
  151. package/main/pairings/FP6BN254/mulFp6BN254.zkasm +201 -0
  152. package/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm +65 -0
  153. package/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm +134 -0
  154. package/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm +128 -0
  155. package/main/pairings/FP6BN254/squareFp6BN254.zkasm +147 -0
  156. package/main/pairings/FP6BN254/subFp6BN254.zkasm +59 -0
  157. package/main/pairings/FPBN254/addFpBN254.zkasm +29 -0
  158. package/main/pairings/FPBN254/invFpBN254.zkasm +55 -0
  159. package/main/pairings/FPBN254/mulFpBN254.zkasm +29 -0
  160. package/main/pairings/FPBN254/reduceFpBN254.zkasm +25 -0
  161. package/main/pairings/FPBN254/squareFpBN254.zkasm +31 -0
  162. package/main/pairings/FPBN254/subFpBN254.zkasm +36 -0
  163. package/main/pairings/FRBN254/reduceFrBN254.zkasm +25 -0
  164. package/main/pairings/constants.zkasm +62 -0
  165. package/main/pairings/ecPairing.zkasm +244 -0
  166. package/main/pairings/finalExpBN254.zkasm +2095 -0
  167. package/main/pairings/halfPairingBN254.zkasm +428 -0
  168. package/main/pairings/loopLengthBN254.zkasm +75 -0
  169. package/main/pairings/millerLoopBN254.zkasm +741 -0
  170. package/main/pairings/pairingBN254.zkasm +481 -0
  171. package/main/pairings/unused/addFp12BN254.zkasm +130 -0
  172. package/main/pairings/unused/expByXCycloFp12BN254.zkasm +411 -0
  173. package/main/pairings/unused/expFp12BN254.zkasm +333 -0
  174. package/main/pairings/unused/subFp12BN254.zkasm +130 -0
  175. package/main/pairings/unused/xPseudoBinDecompBN254.zkasm +68 -0
  176. package/main/pairings/utilsTests/expCycloFp12BN254.zkasm +334 -0
  177. package/main/precompiled/end.zkasm +42 -0
  178. package/main/precompiled/identity.zkasm +99 -0
  179. package/main/precompiled/pre-ecAdd.zkasm +84 -0
  180. package/main/precompiled/pre-ecMul.zkasm +82 -0
  181. package/main/precompiled/pre-ecPairing.zkasm +72 -0
  182. package/main/precompiled/pre-ecrecover.zkasm +71 -0
  183. package/main/precompiled/pre-modexp.zkasm +367 -0
  184. package/main/precompiled/pre-sha2-256.zkasm +125 -0
  185. package/main/precompiled/revert-precompiled.zkasm +25 -0
  186. package/main/precompiled/selector.zkasm +77 -0
  187. package/main/process-change-l2-block.zkasm +147 -0
  188. package/main/process-tx.zkasm +587 -0
  189. package/main/tables/2-exp.zkasm +260 -0
  190. package/main/touched.zkasm +118 -0
  191. package/main/utils.zkasm +2335 -0
  192. package/main/vars.zkasm +117 -0
  193. package/package.json +62 -3
  194. package/test/bytes-length.zkasm +39 -0
  195. package/test/ecrecover.zkasm +538 -0
  196. package/test/lt4-test.zkasm +38 -0
  197. package/test/mstorex.zkasm +191 -0
  198. package/test/opcalldatacopy.ignore.zkasm +331 -0
  199. package/test/performance/read-push.zkasm +71 -0
  200. package/test/read-push.zkasm +304 -0
  201. package/test/testArrayArith.zkasm +1099 -0
  202. package/test/testArrayUtils.zkasm +335 -0
  203. package/test/testCycloFp12ArithBN254.zkasm +548 -0
  204. package/test/testEcAdd.zkasm +252 -0
  205. package/test/testEcMul.zkasm +231 -0
  206. package/test/testEcPairing.zkasm +436 -0
  207. package/test/testFinalExpBn254.zkasm +139 -0
  208. package/test/testFp12ArithBN254.zkasm +692 -0
  209. package/test/testFp2ArithBN254.zkasm +185 -0
  210. package/test/testFp4ArithBN254.zkasm +128 -0
  211. package/test/testFp6ArithBN254.zkasm +260 -0
  212. package/test/testFpArithBN254.zkasm +159 -0
  213. package/test/testFrArithBN254.zkasm +113 -0
  214. package/test/testHalfPairingBN254.zkasm +285 -0
  215. package/test/testModExp.zkasm +586 -0
  216. package/test/testModExpReturn.zkasm +81 -0
  217. package/test/testPairingBN254.zkasm +463 -0
  218. package/test/testPointArithBN254.zkasm +270 -0
  219. package/test/testSHA256.zkasm +27 -0
  220. package/test/touched-assert.zkasm +59 -0
  221. package/test/utils-expAD.zkasm +48 -0
  222. package/test/utils-getLenBytes.zkasm +36 -0
  223. package/tools/audit-tools/registry-op-checker.js +71 -0
  224. package/tools/get-not-used-labels.js +31 -0
  225. package/tools/helpers/helpers.js +47 -0
  226. package/tools/modexp-utils/README.md +5 -0
  227. package/tools/modexp-utils/modexp-test-gen.js +168 -0
  228. package/tools/modexp-utils/modexp-test-int.sage +37 -0
  229. package/tools/parallel-testing/checker.sh +6 -0
  230. package/tools/parallel-testing/gen-parallel-tests.js +78 -0
  231. package/tools/parallel-testing/parallel-tests-sample/sample.test.js +136 -0
  232. 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)