@layerzerolabs/protocol-starknet-v2 0.0.34

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.
Files changed (504) hide show
  1. package/.turbo/turbo-build.log +186 -0
  2. package/.turbo/turbo-lint.log +71 -0
  3. package/.turbo/turbo-test.log +937 -0
  4. package/README.md +41 -0
  5. package/Scarb.lock +211 -0
  6. package/Scarb.toml +2 -0
  7. package/dist/4XD3ZRZ4.cjs +301 -0
  8. package/dist/4XD3ZRZ4.cjs.map +1 -0
  9. package/dist/4Z5IPBC3.js +299 -0
  10. package/dist/4Z5IPBC3.js.map +1 -0
  11. package/dist/5NEZDLVQ.cjs +474 -0
  12. package/dist/5NEZDLVQ.cjs.map +1 -0
  13. package/dist/6JYCOKDE.js +472 -0
  14. package/dist/6JYCOKDE.js.map +1 -0
  15. package/dist/7C4PFMIZ.cjs +1288 -0
  16. package/dist/7C4PFMIZ.cjs.map +1 -0
  17. package/dist/7ZSGGZUE.js +1229 -0
  18. package/dist/7ZSGGZUE.js.map +1 -0
  19. package/dist/ARHOGUYH.cjs +2136 -0
  20. package/dist/ARHOGUYH.cjs.map +1 -0
  21. package/dist/CRCRIUFX.js +1264 -0
  22. package/dist/CRCRIUFX.js.map +1 -0
  23. package/dist/DB7CQSED.cjs +430 -0
  24. package/dist/DB7CQSED.cjs.map +1 -0
  25. package/dist/DFXLWHYP.cjs +1266 -0
  26. package/dist/DFXLWHYP.cjs.map +1 -0
  27. package/dist/EOLZCMCK.js +988 -0
  28. package/dist/EOLZCMCK.js.map +1 -0
  29. package/dist/FFDPTOWG.cjs +331 -0
  30. package/dist/FFDPTOWG.cjs.map +1 -0
  31. package/dist/FOJGEAIO.js +2134 -0
  32. package/dist/FOJGEAIO.js.map +1 -0
  33. package/dist/IWIUMVGB.js +629 -0
  34. package/dist/IWIUMVGB.js.map +1 -0
  35. package/dist/MUEN6AWV.cjs +697 -0
  36. package/dist/MUEN6AWV.cjs.map +1 -0
  37. package/dist/ORE6VBZ4.cjs +990 -0
  38. package/dist/ORE6VBZ4.cjs.map +1 -0
  39. package/dist/OUFKWPZ7.js +732 -0
  40. package/dist/OUFKWPZ7.js.map +1 -0
  41. package/dist/T2QTYQXJ.js +1229 -0
  42. package/dist/T2QTYQXJ.js.map +1 -0
  43. package/dist/UPJTM7BR.cjs +631 -0
  44. package/dist/UPJTM7BR.cjs.map +1 -0
  45. package/dist/VNVNX2P3.cjs +1231 -0
  46. package/dist/VNVNX2P3.cjs.map +1 -0
  47. package/dist/VUOMXK5T.js +6 -0
  48. package/dist/VUOMXK5T.js.map +1 -0
  49. package/dist/WISWRTDG.js +1286 -0
  50. package/dist/WISWRTDG.js.map +1 -0
  51. package/dist/WU5L7YIQ.cjs +1231 -0
  52. package/dist/WU5L7YIQ.cjs.map +1 -0
  53. package/dist/X3B5JDMZ.js +695 -0
  54. package/dist/X3B5JDMZ.js.map +1 -0
  55. package/dist/XYNBDBBV.cjs +297 -0
  56. package/dist/XYNBDBBV.cjs.map +1 -0
  57. package/dist/Y5JFPCYJ.cjs +734 -0
  58. package/dist/Y5JFPCYJ.cjs.map +1 -0
  59. package/dist/YEHL7IYO.js +295 -0
  60. package/dist/YEHL7IYO.js.map +1 -0
  61. package/dist/YJF4D23A.cjs +8 -0
  62. package/dist/YJF4D23A.cjs.map +1 -0
  63. package/dist/YTS44OEA.js +428 -0
  64. package/dist/YTS44OEA.js.map +1 -0
  65. package/dist/Z2NIUZMW.js +329 -0
  66. package/dist/Z2NIUZMW.js.map +1 -0
  67. package/dist/abis/blocked-message-lib.cjs +13 -0
  68. package/dist/abis/blocked-message-lib.cjs.map +1 -0
  69. package/dist/abis/blocked-message-lib.d.ts +338 -0
  70. package/dist/abis/blocked-message-lib.d.ts.map +1 -0
  71. package/dist/abis/blocked-message-lib.js +4 -0
  72. package/dist/abis/blocked-message-lib.js.map +1 -0
  73. package/dist/abis/dvn-fee-lib.cjs +13 -0
  74. package/dist/abis/dvn-fee-lib.cjs.map +1 -0
  75. package/dist/abis/dvn-fee-lib.d.ts +214 -0
  76. package/dist/abis/dvn-fee-lib.d.ts.map +1 -0
  77. package/dist/abis/dvn-fee-lib.js +4 -0
  78. package/dist/abis/dvn-fee-lib.js.map +1 -0
  79. package/dist/abis/dvn.cjs +13 -0
  80. package/dist/abis/dvn.cjs.map +1 -0
  81. package/dist/abis/dvn.d.ts +952 -0
  82. package/dist/abis/dvn.d.ts.map +1 -0
  83. package/dist/abis/dvn.js +4 -0
  84. package/dist/abis/dvn.js.map +1 -0
  85. package/dist/abis/endpoint-v2.cjs +13 -0
  86. package/dist/abis/endpoint-v2.cjs.map +1 -0
  87. package/dist/abis/endpoint-v2.d.ts +1580 -0
  88. package/dist/abis/endpoint-v2.d.ts.map +1 -0
  89. package/dist/abis/endpoint-v2.js +4 -0
  90. package/dist/abis/endpoint-v2.js.map +1 -0
  91. package/dist/abis/executor-fee-lib.cjs +13 -0
  92. package/dist/abis/executor-fee-lib.cjs.map +1 -0
  93. package/dist/abis/executor-fee-lib.d.ts +217 -0
  94. package/dist/abis/executor-fee-lib.d.ts.map +1 -0
  95. package/dist/abis/executor-fee-lib.js +4 -0
  96. package/dist/abis/executor-fee-lib.js.map +1 -0
  97. package/dist/abis/executor.cjs +13 -0
  98. package/dist/abis/executor.cjs.map +1 -0
  99. package/dist/abis/executor.d.ts +914 -0
  100. package/dist/abis/executor.d.ts.map +1 -0
  101. package/dist/abis/executor.js +4 -0
  102. package/dist/abis/executor.js.map +1 -0
  103. package/dist/abis/o-app.cjs +13 -0
  104. package/dist/abis/o-app.cjs.map +1 -0
  105. package/dist/abis/o-app.d.ts +311 -0
  106. package/dist/abis/o-app.d.ts.map +1 -0
  107. package/dist/abis/o-app.js +4 -0
  108. package/dist/abis/o-app.js.map +1 -0
  109. package/dist/abis/oft-adapter.cjs +13 -0
  110. package/dist/abis/oft-adapter.cjs.map +1 -0
  111. package/dist/abis/oft-adapter.d.ts +722 -0
  112. package/dist/abis/oft-adapter.d.ts.map +1 -0
  113. package/dist/abis/oft-adapter.js +4 -0
  114. package/dist/abis/oft-adapter.js.map +1 -0
  115. package/dist/abis/oft.cjs +13 -0
  116. package/dist/abis/oft.cjs.map +1 -0
  117. package/dist/abis/oft.d.ts +922 -0
  118. package/dist/abis/oft.d.ts.map +1 -0
  119. package/dist/abis/oft.js +4 -0
  120. package/dist/abis/oft.js.map +1 -0
  121. package/dist/abis/omni-counter.cjs +13 -0
  122. package/dist/abis/omni-counter.cjs.map +1 -0
  123. package/dist/abis/omni-counter.d.ts +459 -0
  124. package/dist/abis/omni-counter.d.ts.map +1 -0
  125. package/dist/abis/omni-counter.js +4 -0
  126. package/dist/abis/omni-counter.js.map +1 -0
  127. package/dist/abis/price-feed.cjs +13 -0
  128. package/dist/abis/price-feed.cjs.map +1 -0
  129. package/dist/abis/price-feed.d.ts +505 -0
  130. package/dist/abis/price-feed.d.ts.map +1 -0
  131. package/dist/abis/price-feed.js +4 -0
  132. package/dist/abis/price-feed.js.map +1 -0
  133. package/dist/abis/simple-message-lib.cjs +13 -0
  134. package/dist/abis/simple-message-lib.cjs.map +1 -0
  135. package/dist/abis/simple-message-lib.d.ts +535 -0
  136. package/dist/abis/simple-message-lib.d.ts.map +1 -0
  137. package/dist/abis/simple-message-lib.js +4 -0
  138. package/dist/abis/simple-message-lib.js.map +1 -0
  139. package/dist/abis/treasury.cjs +13 -0
  140. package/dist/abis/treasury.cjs.map +1 -0
  141. package/dist/abis/treasury.d.ts +240 -0
  142. package/dist/abis/treasury.d.ts.map +1 -0
  143. package/dist/abis/treasury.js +4 -0
  144. package/dist/abis/treasury.js.map +1 -0
  145. package/dist/abis/ultra-light-node.cjs +13 -0
  146. package/dist/abis/ultra-light-node.cjs.map +1 -0
  147. package/dist/abis/ultra-light-node.d.ts +900 -0
  148. package/dist/abis/ultra-light-node.d.ts.map +1 -0
  149. package/dist/abis/ultra-light-node.js +4 -0
  150. package/dist/abis/ultra-light-node.js.map +1 -0
  151. package/dist/index.cjs +78 -0
  152. package/dist/index.cjs.map +1 -0
  153. package/dist/index.d.ts +15 -0
  154. package/dist/index.d.ts.map +1 -0
  155. package/dist/index.js +17 -0
  156. package/dist/index.js.map +1 -0
  157. package/dist/scripts/build-abi.cjs +28 -0
  158. package/dist/scripts/build-abi.cjs.map +1 -0
  159. package/dist/scripts/build-abi.d.ts +2 -0
  160. package/dist/scripts/build-abi.d.ts.map +1 -0
  161. package/dist/scripts/build-abi.js +26 -0
  162. package/dist/scripts/build-abi.js.map +1 -0
  163. package/layerzero/README.md +244 -0
  164. package/layerzero/Scarb.lock +203 -0
  165. package/layerzero/Scarb.toml +30 -0
  166. package/layerzero/snfoundry.toml +11 -0
  167. package/layerzero/src/common/constants.cairo +26 -0
  168. package/layerzero/src/common/conversions.cairo +16 -0
  169. package/layerzero/src/common/guid.cairo +20 -0
  170. package/layerzero/src/common/packet_v1_codec.cairo +307 -0
  171. package/layerzero/src/common/structs/messaging.cairo +40 -0
  172. package/layerzero/src/common/structs/packet.cairo +31 -0
  173. package/layerzero/src/endpoint/constants.cairo +14 -0
  174. package/layerzero/src/endpoint/endpoint.cairo +688 -0
  175. package/layerzero/src/endpoint/errors.cairo +108 -0
  176. package/layerzero/src/endpoint/events.cairo +124 -0
  177. package/layerzero/src/endpoint/interfaces/endpoint.cairo +286 -0
  178. package/layerzero/src/endpoint/interfaces/layerzero_composer.cairo +62 -0
  179. package/layerzero/src/endpoint/interfaces/layerzero_receiver.cairo +63 -0
  180. package/layerzero/src/endpoint/message_lib_manager/errors.cairo +95 -0
  181. package/layerzero/src/endpoint/message_lib_manager/events.cairo +90 -0
  182. package/layerzero/src/endpoint/message_lib_manager/interface.cairo +449 -0
  183. package/layerzero/src/endpoint/message_lib_manager/message_lib_manager.cairo +720 -0
  184. package/layerzero/src/endpoint/message_lib_manager/structs.cairo +33 -0
  185. package/layerzero/src/endpoint/messaging_channel/errors.cairo +37 -0
  186. package/layerzero/src/endpoint/messaging_channel/events.cairo +58 -0
  187. package/layerzero/src/endpoint/messaging_channel/interface.cairo +171 -0
  188. package/layerzero/src/endpoint/messaging_channel/messaging_channel.cairo +453 -0
  189. package/layerzero/src/endpoint/messaging_composer/errors.cairo +46 -0
  190. package/layerzero/src/endpoint/messaging_composer/events.cairo +67 -0
  191. package/layerzero/src/endpoint/messaging_composer/interface.cairo +132 -0
  192. package/layerzero/src/endpoint/messaging_composer/messaging_composer.cairo +223 -0
  193. package/layerzero/src/lib.cairo +189 -0
  194. package/layerzero/src/message_lib/blocked_message_lib.cairo +114 -0
  195. package/layerzero/src/message_lib/interface.cairo +63 -0
  196. package/layerzero/src/message_lib/sml/errors.cairo +23 -0
  197. package/layerzero/src/message_lib/sml/events.cairo +32 -0
  198. package/layerzero/src/message_lib/sml/simple_message_lib.cairo +312 -0
  199. package/layerzero/src/message_lib/structs.cairo +22 -0
  200. package/layerzero/src/message_lib/uln/errors.cairo +128 -0
  201. package/layerzero/src/message_lib/uln/events.cairo +97 -0
  202. package/layerzero/src/message_lib/uln/interface.cairo +83 -0
  203. package/layerzero/src/message_lib/uln/options.cairo +64 -0
  204. package/layerzero/src/message_lib/uln/structs/executor_config.cairo +35 -0
  205. package/layerzero/src/message_lib/uln/structs/payment_info.cairo +7 -0
  206. package/layerzero/src/message_lib/uln/structs/uln_config.cairo +155 -0
  207. package/layerzero/src/message_lib/uln/structs/uln_config_storage_node.cairo +91 -0
  208. package/layerzero/src/message_lib/uln/structs/verification.cairo +7 -0
  209. package/layerzero/src/message_lib/uln/ultra_light_node.cairo +965 -0
  210. package/layerzero/src/oapps/common/oapp_options_type_3/errors.cairo +22 -0
  211. package/layerzero/src/oapps/common/oapp_options_type_3/events.cairo +6 -0
  212. package/layerzero/src/oapps/common/oapp_options_type_3/interface.cairo +34 -0
  213. package/layerzero/src/oapps/common/oapp_options_type_3/oapp_options_type_3.cairo +120 -0
  214. package/layerzero/src/oapps/common/oapp_options_type_3/structs.cairo +6 -0
  215. package/layerzero/src/oapps/counter/constants.cairo +3 -0
  216. package/layerzero/src/oapps/counter/counter.cairo +170 -0
  217. package/layerzero/src/oapps/counter/interface.cairo +27 -0
  218. package/layerzero/src/oapps/counter/structs.cairo +20 -0
  219. package/layerzero/src/oapps/message_inspector/interface.cairo +21 -0
  220. package/layerzero/src/oapps/oapp/errors.cairo +72 -0
  221. package/layerzero/src/oapps/oapp/events.cairo +9 -0
  222. package/layerzero/src/oapps/oapp/interface.cairo +67 -0
  223. package/layerzero/src/oapps/oapp/oapp.cairo +70 -0
  224. package/layerzero/src/oapps/oapp/oapp_core.cairo +448 -0
  225. package/layerzero/src/oapps/oft/errors.cairo +42 -0
  226. package/layerzero/src/oapps/oft/events.cairo +33 -0
  227. package/layerzero/src/oapps/oft/interface.cairo +87 -0
  228. package/layerzero/src/oapps/oft/oft.cairo +188 -0
  229. package/layerzero/src/oapps/oft/oft_adapter.cairo +175 -0
  230. package/layerzero/src/oapps/oft/oft_compose_msg_codec.cairo +128 -0
  231. package/layerzero/src/oapps/oft/oft_core.cairo +542 -0
  232. package/layerzero/src/oapps/oft/oft_msg_codec.cairo +131 -0
  233. package/layerzero/src/oapps/oft/structs.cairo +72 -0
  234. package/layerzero/src/treasury/errors.cairo +22 -0
  235. package/layerzero/src/treasury/events.cairo +5 -0
  236. package/layerzero/src/treasury/interfaces/layerzero_treasury.cairo +54 -0
  237. package/layerzero/src/treasury/interfaces/lz_token_fee_lib.cairo +45 -0
  238. package/layerzero/src/treasury/interfaces/treasury_admin.cairo +39 -0
  239. package/layerzero/src/treasury/treasury.cairo +140 -0
  240. package/layerzero/src/workers/access_control.cairo +11 -0
  241. package/layerzero/src/workers/base/base.cairo +238 -0
  242. package/layerzero/src/workers/base/errors.cairo +24 -0
  243. package/layerzero/src/workers/base/events.cairo +43 -0
  244. package/layerzero/src/workers/base/interface.cairo +93 -0
  245. package/layerzero/src/workers/base/structs.cairo +10 -0
  246. package/layerzero/src/workers/common.cairo +59 -0
  247. package/layerzero/src/workers/dvn/constants.cairo +11 -0
  248. package/layerzero/src/workers/dvn/dvn.cairo +338 -0
  249. package/layerzero/src/workers/dvn/errors.cairo +80 -0
  250. package/layerzero/src/workers/dvn/events.cairo +30 -0
  251. package/layerzero/src/workers/dvn/fee_lib/dvn_fee_lib.cairo +152 -0
  252. package/layerzero/src/workers/dvn/fee_lib/interface.cairo +45 -0
  253. package/layerzero/src/workers/dvn/interface.cairo +131 -0
  254. package/layerzero/src/workers/dvn/options.cairo +125 -0
  255. package/layerzero/src/workers/dvn/structs.cairo +51 -0
  256. package/layerzero/src/workers/executor/errors.cairo +159 -0
  257. package/layerzero/src/workers/executor/events.cairo +32 -0
  258. package/layerzero/src/workers/executor/executor.cairo +392 -0
  259. package/layerzero/src/workers/executor/fee_lib/executor_fee_lib.cairo +160 -0
  260. package/layerzero/src/workers/executor/fee_lib/interface.cairo +87 -0
  261. package/layerzero/src/workers/executor/interface.cairo +131 -0
  262. package/layerzero/src/workers/executor/options.cairo +244 -0
  263. package/layerzero/src/workers/executor/structs.cairo +119 -0
  264. package/layerzero/src/workers/interface.cairo +32 -0
  265. package/layerzero/src/workers/price_feed/constants.cairo +7 -0
  266. package/layerzero/src/workers/price_feed/errors.cairo +28 -0
  267. package/layerzero/src/workers/price_feed/events.cairo +13 -0
  268. package/layerzero/src/workers/price_feed/interface.cairo +264 -0
  269. package/layerzero/src/workers/price_feed/price_feed.cairo +392 -0
  270. package/layerzero/src/workers/price_feed/structs.cairo +74 -0
  271. package/layerzero/tests/common/test_constants.cairo +21 -0
  272. package/layerzero/tests/common/test_guid.cairo +232 -0
  273. package/layerzero/tests/common/test_packet_v1_codec.cairo +372 -0
  274. package/layerzero/tests/common/utils.cairo +23 -0
  275. package/layerzero/tests/e2e/oft_utils.cairo +121 -0
  276. package/layerzero/tests/e2e/test_counter_with_sml.cairo +194 -0
  277. package/layerzero/tests/e2e/test_counter_with_uln.cairo +352 -0
  278. package/layerzero/tests/e2e/test_dvn.cairo +406 -0
  279. package/layerzero/tests/e2e/test_lz_token.cairo +354 -0
  280. package/layerzero/tests/e2e/test_oft_compose_with_uln.cairo +364 -0
  281. package/layerzero/tests/e2e/test_oft_with_sml.cairo +240 -0
  282. package/layerzero/tests/e2e/test_oft_with_uln.cairo +299 -0
  283. package/layerzero/tests/e2e/utils.cairo +490 -0
  284. package/layerzero/tests/endpoint/message_lib_manager/test_message_lib_manager.cairo +2051 -0
  285. package/layerzero/tests/endpoint/message_lib_manager/utils.cairo +45 -0
  286. package/layerzero/tests/endpoint/messaging_channel/test_messaging_channel.cairo +621 -0
  287. package/layerzero/tests/endpoint/messaging_channel/utils.cairo +96 -0
  288. package/layerzero/tests/endpoint/messaging_composer/test_messaging_composer.cairo +456 -0
  289. package/layerzero/tests/endpoint/messaging_composer/utils.cairo +75 -0
  290. package/layerzero/tests/endpoint/test_endpoint_commit.cairo +763 -0
  291. package/layerzero/tests/endpoint/test_endpoint_lzreceive.cairo +1253 -0
  292. package/layerzero/tests/endpoint/test_endpoint_quote.cairo +71 -0
  293. package/layerzero/tests/endpoint/test_endpoint_send.cairo +1327 -0
  294. package/layerzero/tests/endpoint/utils.cairo +129 -0
  295. package/layerzero/tests/fuzzable/blockchain_config.cairo +89 -0
  296. package/layerzero/tests/fuzzable/bytes32.cairo +16 -0
  297. package/layerzero/tests/fuzzable/contract_address.cairo +67 -0
  298. package/layerzero/tests/fuzzable/dst_config.cairo +37 -0
  299. package/layerzero/tests/fuzzable/eid.cairo +23 -0
  300. package/layerzero/tests/fuzzable/eth_address.cairo +17 -0
  301. package/layerzero/tests/fuzzable/expiry.cairo +27 -0
  302. package/layerzero/tests/fuzzable/felt_array.cairo +38 -0
  303. package/layerzero/tests/fuzzable/inbound_params.cairo +21 -0
  304. package/layerzero/tests/fuzzable/keys.cairo +16 -0
  305. package/layerzero/tests/fuzzable/model_type.cairo +27 -0
  306. package/layerzero/tests/fuzzable/origin.cairo +21 -0
  307. package/layerzero/tests/fuzzable/price.cairo +32 -0
  308. package/layerzero/tests/fuzzable/role_admin.cairo +29 -0
  309. package/layerzero/tests/fuzzable/small_byte_array.cairo +61 -0
  310. package/layerzero/tests/lib.cairo +177 -0
  311. package/layerzero/tests/message_lib/sml/test_simple_message_lib.cairo +224 -0
  312. package/layerzero/tests/message_lib/uln/test_uln_admin.cairo +2150 -0
  313. package/layerzero/tests/message_lib/uln/test_uln_config.cairo +527 -0
  314. package/layerzero/tests/message_lib/uln/test_uln_config_storage_node.cairo +69 -0
  315. package/layerzero/tests/message_lib/uln/test_uln_executor_config.cairo +173 -0
  316. package/layerzero/tests/message_lib/uln/test_uln_options.cairo +329 -0
  317. package/layerzero/tests/message_lib/uln/test_uln_quote.cairo +1038 -0
  318. package/layerzero/tests/message_lib/uln/test_uln_receive.cairo +715 -0
  319. package/layerzero/tests/message_lib/uln/test_uln_send.cairo +1155 -0
  320. package/layerzero/tests/message_lib/uln/utils.cairo +59 -0
  321. package/layerzero/tests/mocks/composer_target.cairo +76 -0
  322. package/layerzero/tests/mocks/endpoint.cairo +199 -0
  323. package/layerzero/tests/mocks/erc20/erc20.cairo +50 -0
  324. package/layerzero/tests/mocks/erc20/interface.cairo +8 -0
  325. package/layerzero/tests/mocks/message_inspector/message_inspector.cairo +17 -0
  326. package/layerzero/tests/mocks/message_lib_manager.cairo +98 -0
  327. package/layerzero/tests/mocks/messaging_channel/interface.cairo +23 -0
  328. package/layerzero/tests/mocks/messaging_channel/messaging_channel.cairo +138 -0
  329. package/layerzero/tests/mocks/messaging_composer.cairo +171 -0
  330. package/layerzero/tests/mocks/oapp_core/interface.cairo +53 -0
  331. package/layerzero/tests/mocks/oapp_core/oapp_core.cairo +142 -0
  332. package/layerzero/tests/mocks/oapp_options_type3.cairo +42 -0
  333. package/layerzero/tests/mocks/oft_core/interface.cairo +28 -0
  334. package/layerzero/tests/mocks/oft_core/oft_core.cairo +242 -0
  335. package/layerzero/tests/mocks/receiver.cairo +54 -0
  336. package/layerzero/tests/mocks/treasury/lz_token_fee_lib.cairo +57 -0
  337. package/layerzero/tests/mocks/treasury/treasury.cairo +74 -0
  338. package/layerzero/tests/mocks/uln_config/interface.cairo +12 -0
  339. package/layerzero/tests/mocks/uln_config/uln_config.cairo +35 -0
  340. package/layerzero/tests/mocks/workers/base.cairo +80 -0
  341. package/layerzero/tests/mocks/workers/dvn.cairo +115 -0
  342. package/layerzero/tests/mocks/workers/executor/decode/decode.cairo +97 -0
  343. package/layerzero/tests/mocks/workers/executor/decode/interface.cairo +59 -0
  344. package/layerzero/tests/mocks/workers/executor/executor.cairo +176 -0
  345. package/layerzero/tests/oapps/common/test_oapp_options_type_3.cairo +279 -0
  346. package/layerzero/tests/oapps/oft/test_oft_adapter.cairo +441 -0
  347. package/layerzero/tests/oapps/oft/test_oft_compose_msg_codec.cairo +139 -0
  348. package/layerzero/tests/oapps/oft/test_oft_core.cairo +751 -0
  349. package/layerzero/tests/oapps/oft/test_oft_msg_codec.cairo +268 -0
  350. package/layerzero/tests/oapps/test_counter.cairo +470 -0
  351. package/layerzero/tests/oapps/test_oapp_core.cairo +750 -0
  352. package/layerzero/tests/treasury/test_lz_token_fee_lib.cairo +63 -0
  353. package/layerzero/tests/treasury/test_treasury.cairo +458 -0
  354. package/layerzero/tests/treasury/utils.cairo +8 -0
  355. package/layerzero/tests/utils.cairo +48 -0
  356. package/layerzero/tests/workers/base/test_worker_base.cairo +1097 -0
  357. package/layerzero/tests/workers/base/utils.cairo +76 -0
  358. package/layerzero/tests/workers/dvn/fee_lib/test_dvn_fee_lib.cairo +361 -0
  359. package/layerzero/tests/workers/dvn/test_dvn.cairo +1101 -0
  360. package/layerzero/tests/workers/dvn/test_dvn_options.cairo +312 -0
  361. package/layerzero/tests/workers/dvn/utils.cairo +236 -0
  362. package/layerzero/tests/workers/executor/fee_lib/test_executor_fee_lib.cairo +223 -0
  363. package/layerzero/tests/workers/executor/test_decode.cairo +612 -0
  364. package/layerzero/tests/workers/executor/test_executor.cairo +1472 -0
  365. package/layerzero/tests/workers/executor/utils.cairo +296 -0
  366. package/layerzero/tests/workers/price_feed/test_price_feed.cairo +879 -0
  367. package/layerzero/tests/workers/price_feed/utils.cairo +37 -0
  368. package/libs/enumerable_set/Scarb.lock +24 -0
  369. package/libs/enumerable_set/Scarb.toml +17 -0
  370. package/libs/enumerable_set/src/enumerable_set.cairo +118 -0
  371. package/libs/enumerable_set/src/lib.cairo +4 -0
  372. package/libs/enumerable_set/tests/lib.cairo +5 -0
  373. package/libs/enumerable_set/tests/mocks/mock_enumerable_set.cairo +61 -0
  374. package/libs/enumerable_set/tests/test_enumerable_set.cairo +379 -0
  375. package/libs/lz_utils/Scarb.lock +24 -0
  376. package/libs/lz_utils/Scarb.toml +17 -0
  377. package/libs/lz_utils/src/bytes.cairo +33 -0
  378. package/libs/lz_utils/src/error.cairo +12 -0
  379. package/libs/lz_utils/src/keccak.cairo +28 -0
  380. package/libs/lz_utils/src/lib.cairo +3 -0
  381. package/libs/multisig/Scarb.lock +172 -0
  382. package/libs/multisig/Scarb.toml +23 -0
  383. package/libs/multisig/src/errors.cairo +84 -0
  384. package/libs/multisig/src/events.cairo +13 -0
  385. package/libs/multisig/src/interface.cairo +73 -0
  386. package/libs/multisig/src/lib.cairo +7 -0
  387. package/libs/multisig/src/multisig.cairo +241 -0
  388. package/libs/multisig/tests/lib.cairo +4 -0
  389. package/libs/multisig/tests/mocks/mock_multisig.cairo +57 -0
  390. package/libs/multisig/tests/test_multisig.cairo +452 -0
  391. package/package.json +41 -0
  392. package/src/scripts/build-abi.ts +51 -0
  393. package/target/CACHEDIR.TAG +3 -0
  394. package/target/dev/.fingerprint/alexandria_bytes-5ea6u5t70d7qi/alexandria_bytes +1 -0
  395. package/target/dev/.fingerprint/alexandria_data_structures-0aue3g6q80gs0/alexandria_data_structures +1 -0
  396. package/target/dev/.fingerprint/alexandria_math-h2fi7jdq4isuu/alexandria_math +1 -0
  397. package/target/dev/.fingerprint/core-lq3u730l5p1ag/core +1 -0
  398. package/target/dev/.fingerprint/core-vf7fc6rvic5vi/core +1 -0
  399. package/target/dev/.fingerprint/enumerable_set-eaerkg8njl85o/enumerable_set +1 -0
  400. package/target/dev/.fingerprint/enumerable_set-r54oje7t06ku8/enumerable_set +1 -0
  401. package/target/dev/.fingerprint/layerzero-oqgdqsaddpi2k/layerzero +1 -0
  402. package/target/dev/.fingerprint/lz_utils-kfkkeueiqg0pa/lz_utils +1 -0
  403. package/target/dev/.fingerprint/lz_utils-u4v1os6e7gkng/lz_utils +1 -0
  404. package/target/dev/.fingerprint/multisig-0fjetugejecge/multisig +1 -0
  405. package/target/dev/.fingerprint/multisig-6j5kqs436hm54/multisig +1 -0
  406. package/target/dev/.fingerprint/openzeppelin-ei1id1hu088lo/openzeppelin +1 -0
  407. package/target/dev/.fingerprint/openzeppelin-j9d5nd1qhfnu6/openzeppelin +1 -0
  408. package/target/dev/.fingerprint/openzeppelin_access-3oa41aikpaek0/openzeppelin_access +1 -0
  409. package/target/dev/.fingerprint/openzeppelin_access-p5h849v8so76q/openzeppelin_access +1 -0
  410. package/target/dev/.fingerprint/openzeppelin_account-4qhv5fks84g9u/openzeppelin_account +1 -0
  411. package/target/dev/.fingerprint/openzeppelin_account-hgbm8ln9ah7rm/openzeppelin_account +1 -0
  412. package/target/dev/.fingerprint/openzeppelin_finance-n70q9al0cps8i/openzeppelin_finance +1 -0
  413. package/target/dev/.fingerprint/openzeppelin_finance-nnd4f8703t3ak/openzeppelin_finance +1 -0
  414. package/target/dev/.fingerprint/openzeppelin_governance-3gnk21ubp5lis/openzeppelin_governance +1 -0
  415. package/target/dev/.fingerprint/openzeppelin_governance-rj1bfont4fij4/openzeppelin_governance +1 -0
  416. package/target/dev/.fingerprint/openzeppelin_introspection-3fja9hd1gvbcq/openzeppelin_introspection +1 -0
  417. package/target/dev/.fingerprint/openzeppelin_introspection-jc3nf5525eet6/openzeppelin_introspection +1 -0
  418. package/target/dev/.fingerprint/openzeppelin_merkle_tree-4en77ogr2r2l2/openzeppelin_merkle_tree +1 -0
  419. package/target/dev/.fingerprint/openzeppelin_merkle_tree-4t190frqs4db8/openzeppelin_merkle_tree +1 -0
  420. package/target/dev/.fingerprint/openzeppelin_presets-aqb0f6p9c0bp6/openzeppelin_presets +1 -0
  421. package/target/dev/.fingerprint/openzeppelin_presets-nseg8korhin8e/openzeppelin_presets +1 -0
  422. package/target/dev/.fingerprint/openzeppelin_security-g7p73ji1ih1qg/openzeppelin_security +1 -0
  423. package/target/dev/.fingerprint/openzeppelin_security-qp5328v80452u/openzeppelin_security +1 -0
  424. package/target/dev/.fingerprint/openzeppelin_token-jjf7tl9rphc6k/openzeppelin_token +1 -0
  425. package/target/dev/.fingerprint/openzeppelin_token-r6s43vlpj6rqk/openzeppelin_token +1 -0
  426. package/target/dev/.fingerprint/openzeppelin_upgrades-0dpbnre7engca/openzeppelin_upgrades +1 -0
  427. package/target/dev/.fingerprint/openzeppelin_upgrades-2sqgvbuv9s800/openzeppelin_upgrades +1 -0
  428. package/target/dev/.fingerprint/openzeppelin_utils-mj395ivff1ffo/openzeppelin_utils +1 -0
  429. package/target/dev/.fingerprint/openzeppelin_utils-oh1hse8sjumgm/openzeppelin_utils +1 -0
  430. package/target/dev/.fingerprint/starkware_utils-1qnnjnq0pf9u0/starkware_utils +1 -0
  431. package/target/dev/.fingerprint/starkware_utils-mh8e3te65lju4/starkware_utils +1 -0
  432. package/target/dev/enumerable_set.sierra.json +1 -0
  433. package/target/dev/incremental/alexandria_bytes-5ea6u5t70d7qi.bin +0 -0
  434. package/target/dev/incremental/alexandria_data_structures-0aue3g6q80gs0.bin +0 -0
  435. package/target/dev/incremental/alexandria_math-h2fi7jdq4isuu.bin +0 -0
  436. package/target/dev/incremental/core-lq3u730l5p1ag.bin +0 -0
  437. package/target/dev/incremental/core-vf7fc6rvic5vi.bin +0 -0
  438. package/target/dev/incremental/enumerable_set-eaerkg8njl85o.bin +0 -0
  439. package/target/dev/incremental/enumerable_set-r54oje7t06ku8.bin +0 -0
  440. package/target/dev/incremental/layerzero-oqgdqsaddpi2k.bin +0 -0
  441. package/target/dev/incremental/lz_utils-kfkkeueiqg0pa.bin +0 -0
  442. package/target/dev/incremental/lz_utils-u4v1os6e7gkng.bin +0 -0
  443. package/target/dev/incremental/multisig-0fjetugejecge.bin +0 -0
  444. package/target/dev/incremental/multisig-6j5kqs436hm54.bin +0 -0
  445. package/target/dev/incremental/openzeppelin-ei1id1hu088lo.bin +0 -0
  446. package/target/dev/incremental/openzeppelin-j9d5nd1qhfnu6.bin +0 -0
  447. package/target/dev/incremental/openzeppelin_access-3oa41aikpaek0.bin +0 -0
  448. package/target/dev/incremental/openzeppelin_access-p5h849v8so76q.bin +0 -0
  449. package/target/dev/incremental/openzeppelin_account-4qhv5fks84g9u.bin +0 -0
  450. package/target/dev/incremental/openzeppelin_account-hgbm8ln9ah7rm.bin +0 -0
  451. package/target/dev/incremental/openzeppelin_finance-n70q9al0cps8i.bin +0 -0
  452. package/target/dev/incremental/openzeppelin_finance-nnd4f8703t3ak.bin +0 -0
  453. package/target/dev/incremental/openzeppelin_governance-3gnk21ubp5lis.bin +0 -0
  454. package/target/dev/incremental/openzeppelin_governance-rj1bfont4fij4.bin +0 -0
  455. package/target/dev/incremental/openzeppelin_introspection-3fja9hd1gvbcq.bin +0 -0
  456. package/target/dev/incremental/openzeppelin_introspection-jc3nf5525eet6.bin +0 -0
  457. package/target/dev/incremental/openzeppelin_merkle_tree-4en77ogr2r2l2.bin +0 -0
  458. package/target/dev/incremental/openzeppelin_merkle_tree-4t190frqs4db8.bin +0 -0
  459. package/target/dev/incremental/openzeppelin_presets-aqb0f6p9c0bp6.bin +0 -0
  460. package/target/dev/incremental/openzeppelin_presets-nseg8korhin8e.bin +0 -0
  461. package/target/dev/incremental/openzeppelin_security-g7p73ji1ih1qg.bin +0 -0
  462. package/target/dev/incremental/openzeppelin_security-qp5328v80452u.bin +0 -0
  463. package/target/dev/incremental/openzeppelin_token-jjf7tl9rphc6k.bin +0 -0
  464. package/target/dev/incremental/openzeppelin_token-r6s43vlpj6rqk.bin +0 -0
  465. package/target/dev/incremental/openzeppelin_upgrades-0dpbnre7engca.bin +0 -0
  466. package/target/dev/incremental/openzeppelin_upgrades-2sqgvbuv9s800.bin +0 -0
  467. package/target/dev/incremental/openzeppelin_utils-mj395ivff1ffo.bin +0 -0
  468. package/target/dev/incremental/openzeppelin_utils-oh1hse8sjumgm.bin +0 -0
  469. package/target/dev/incremental/starkware_utils-1qnnjnq0pf9u0.bin +0 -0
  470. package/target/dev/incremental/starkware_utils-mh8e3te65lju4.bin +0 -0
  471. package/target/dev/layerzero.starknet_artifacts.json +1 -0
  472. package/target/dev/layerzero_BlockedMessageLib.compiled_contract_class.json +1 -0
  473. package/target/dev/layerzero_BlockedMessageLib.contract_class.json +1 -0
  474. package/target/dev/layerzero_Dvn.compiled_contract_class.json +1 -0
  475. package/target/dev/layerzero_Dvn.contract_class.json +1 -0
  476. package/target/dev/layerzero_DvnFeeLib.compiled_contract_class.json +1 -0
  477. package/target/dev/layerzero_DvnFeeLib.contract_class.json +1 -0
  478. package/target/dev/layerzero_Endpoint.compiled_contract_class.json +1 -0
  479. package/target/dev/layerzero_Endpoint.contract_class.json +1 -0
  480. package/target/dev/layerzero_Executor.compiled_contract_class.json +1 -0
  481. package/target/dev/layerzero_Executor.contract_class.json +1 -0
  482. package/target/dev/layerzero_ExecutorFeeLib.compiled_contract_class.json +1 -0
  483. package/target/dev/layerzero_ExecutorFeeLib.contract_class.json +1 -0
  484. package/target/dev/layerzero_OApp.compiled_contract_class.json +1 -0
  485. package/target/dev/layerzero_OApp.contract_class.json +1 -0
  486. package/target/dev/layerzero_OFT.compiled_contract_class.json +1 -0
  487. package/target/dev/layerzero_OFT.contract_class.json +1 -0
  488. package/target/dev/layerzero_OFTAdapter.compiled_contract_class.json +1 -0
  489. package/target/dev/layerzero_OFTAdapter.contract_class.json +1 -0
  490. package/target/dev/layerzero_OmniCounter.compiled_contract_class.json +1 -0
  491. package/target/dev/layerzero_OmniCounter.contract_class.json +1 -0
  492. package/target/dev/layerzero_PriceFeed.compiled_contract_class.json +1 -0
  493. package/target/dev/layerzero_PriceFeed.contract_class.json +1 -0
  494. package/target/dev/layerzero_SimpleMessageLib.compiled_contract_class.json +1 -0
  495. package/target/dev/layerzero_SimpleMessageLib.contract_class.json +1 -0
  496. package/target/dev/layerzero_Treasury.compiled_contract_class.json +1 -0
  497. package/target/dev/layerzero_Treasury.contract_class.json +1 -0
  498. package/target/dev/layerzero_UltraLightNode.compiled_contract_class.json +1 -0
  499. package/target/dev/layerzero_UltraLightNode.contract_class.json +1 -0
  500. package/target/dev/lz_utils.sierra.json +1 -0
  501. package/target/dev/multisig.sierra.json +1 -0
  502. package/tools/update_contracts.sh +19 -0
  503. package/tsconfig.json +20 -0
  504. package/tsup.config.ts +7 -0
@@ -0,0 +1,1101 @@
1
+ //! DVN tests
2
+
3
+ use layerzero::common::constants::ZERO_ADDRESS;
4
+ use layerzero::workers::access_control::{ADMIN_ROLE, DEFAULT_ADMIN_ROLE, MESSAGE_LIB_ROLE};
5
+ use layerzero::workers::dvn::dvn::Dvn;
6
+ use layerzero::workers::dvn::interface::{IDvnDispatcherTrait, IDvnSafeDispatcherTrait};
7
+ use layerzero::workers::dvn::structs::{DstConfig, ExecuteParam, SetDstConfigParams};
8
+ use layerzero::workers::dvn::{errors, events};
9
+ use layerzero::workers::interface::ILayerZeroWorkerDispatcher;
10
+ use multisig::MultisigComponent;
11
+ use multisig::errors::{err_only_multisig, err_signature_error};
12
+ use multisig::events::{SignerSet, ThresholdSet};
13
+ use multisig::interface::{IMultisigDispatcher, IMultisigDispatcherTrait};
14
+ use openzeppelin::access::accesscontrol::AccessControlComponent;
15
+ use openzeppelin::access::accesscontrol::interface::IAccessControlDispatcherTrait;
16
+ use snforge_std::fuzzable::{FuzzableU16, FuzzableU32, FuzzableU64};
17
+ use snforge_std::{
18
+ DeclareResultTrait, EventSpyAssertionsTrait, EventSpyTrait, declare, get_class_hash, spy_events,
19
+ start_cheat_block_timestamp, start_cheat_caller_address, stop_cheat_block_timestamp,
20
+ stop_cheat_caller_address,
21
+ };
22
+ use starknet::account::Call;
23
+ use starknet::{ContractAddress, EthAddress};
24
+ use starkware_utils_testing::test_utils::{assert_panic_with_error, cheat_caller_address_once};
25
+ use crate::fuzzable::contract_address::{
26
+ ContractAddressArrayList, FuzzableContractAddress, FuzzableContractAddresses,
27
+ };
28
+ use crate::fuzzable::dst_config::FuzzableDvnDstConfig;
29
+ use crate::fuzzable::eid::{Eid, FuzzableEid};
30
+ use crate::fuzzable::eth_address::FuzzableEthAddress;
31
+ use crate::fuzzable::expiry::{Expiry, FuzzableExpiry};
32
+ use crate::fuzzable::felt_array::{Felt252ArrayList, FuzzableFelt252Array};
33
+ use crate::fuzzable::keys::FuzzableKeyPair;
34
+ use crate::fuzzable::role_admin::{FuzzableRoleAdmin, RoleAdmin};
35
+ use crate::mocks::workers::dvn::MockDVN;
36
+ use crate::workers::dvn::utils::{
37
+ DvnDeploy, KeyPair, deploy_dvn, deploy_dvn_with_additional_roles, sign_for_test_k1,
38
+ sort_signatures,
39
+ };
40
+
41
+ /// Default multiplier basis points (120%)
42
+ const DEFAULT_MULTIPLIER_BPS: u16 = 12000;
43
+
44
+ /// Initial roles are set correctly
45
+ #[test]
46
+ #[fuzzer(runs: 10)]
47
+ fn sets_initial_roles(
48
+ role_admin: RoleAdmin,
49
+ vid: u32,
50
+ message_libs: ContractAddressArrayList,
51
+ admins: ContractAddressArrayList,
52
+ ) {
53
+ let role_admin = role_admin.address;
54
+ let DvnDeploy {
55
+ access_control, ..,
56
+ } = deploy_dvn(message_libs.arr.span(), vid, role_admin, admins.arr.span());
57
+
58
+ // Check that role admin was set correctly
59
+ assert(access_control.has_role(DEFAULT_ADMIN_ROLE, role_admin), 'Role admin should be set');
60
+ assert(!access_control.has_role(ADMIN_ROLE, role_admin), 'Role admin should not be admin');
61
+ assert!(
62
+ !access_control.has_role(MESSAGE_LIB_ROLE, role_admin), "Role admin should not be msg lib",
63
+ );
64
+
65
+ // Check that admin roles were set correctly
66
+ for admin in admins.arr {
67
+ assert(access_control.has_role(ADMIN_ROLE, admin), 'Admin role should be set');
68
+ assert(!access_control.has_role(MESSAGE_LIB_ROLE, admin), 'Admin should not be msg lib');
69
+ assert(
70
+ !access_control.has_role(DEFAULT_ADMIN_ROLE, admin), 'Admin should not be role admin',
71
+ );
72
+ }
73
+
74
+ // Check that message lib roles were set correctly
75
+ for msg_lib in message_libs.arr {
76
+ assert(access_control.has_role(MESSAGE_LIB_ROLE, msg_lib), 'Msg lib role should be set');
77
+ assert(!access_control.has_role(ADMIN_ROLE, msg_lib), 'Msg lib should not be admin');
78
+ assert!(
79
+ !access_control.has_role(DEFAULT_ADMIN_ROLE, msg_lib),
80
+ "Msg lib should not be role admin",
81
+ );
82
+ }
83
+ }
84
+
85
+ /// Set dst configs succeeds when caller is admin
86
+ #[test]
87
+ #[fuzzer(runs: 10)]
88
+ fn should_set_dst_config_when_caller_is_admin(
89
+ role_admin: RoleAdmin,
90
+ admin: ContractAddress,
91
+ vid: u32,
92
+ dst_eid_1: Eid,
93
+ dst_eid_2: Eid,
94
+ config_1: DstConfig,
95
+ config_2: DstConfig,
96
+ ) {
97
+ let role_admin = role_admin.address;
98
+ let DvnDeploy {
99
+ dvn, dispatcher, ..,
100
+ } = deploy_dvn(array![].span(), vid, role_admin, array![admin].span());
101
+
102
+ let dst_eid_1 = dst_eid_1.eid;
103
+ let dst_eid_2 = dst_eid_2.eid;
104
+ let params = array![
105
+ SetDstConfigParams { dst_eid: dst_eid_1, config: config_1 },
106
+ SetDstConfigParams { dst_eid: dst_eid_2, config: config_2 },
107
+ ];
108
+
109
+ // Set the dst configs
110
+ // Caller has admin role
111
+ cheat_caller_address_once(dvn, admin);
112
+ dispatcher.set_dst_config(params);
113
+
114
+ // Check that the configs were set correctly
115
+ assert(dispatcher.get_dst_config(dst_eid_1) == config_1, 'Config 1 should be set');
116
+ assert(dispatcher.get_dst_config(dst_eid_2) == config_2, 'Config 2 should be set');
117
+ }
118
+
119
+ /// Execute call data succeeds when caller is admin
120
+ #[test]
121
+ #[fuzzer(runs: 10)]
122
+ fn should_execute_call_data_when_caller_is_admin(
123
+ role_admin: RoleAdmin,
124
+ admins: ContractAddressArrayList,
125
+ vid: u32,
126
+ dst_eid: Eid,
127
+ config: DstConfig,
128
+ key_pair_1: KeyPair,
129
+ key_pair_2: KeyPair,
130
+ expiry: Expiry,
131
+ ) {
132
+ let dst_eid = dst_eid.eid;
133
+ let role_admin = role_admin.address;
134
+ let expiration: u256 = expiry.expiry.into();
135
+
136
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
137
+ let DvnDeploy {
138
+ dvn, dispatcher, ..,
139
+ } =
140
+ deploy_dvn_with_additional_roles(
141
+ array![].span(), vid, signers, role_admin, admins.arr.span(),
142
+ );
143
+
144
+ // create call data for set dst config
145
+ let set_dst_config_params = array![SetDstConfigParams { dst_eid, config }];
146
+
147
+ let mut serialized_config = array![];
148
+ set_dst_config_params.serialize(ref serialized_config);
149
+
150
+ let call_data = Call {
151
+ to: dvn, selector: selector!("set_dst_config"), calldata: serialized_config.into(),
152
+ };
153
+
154
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
155
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
156
+ let execute_params = array![
157
+ ExecuteParam { vid, call_data, expiration, signatures: signatures.into() },
158
+ ];
159
+
160
+ // Execute with the given params for each admin
161
+ for admin in admins.arr {
162
+ // Caller has admin role
163
+ start_cheat_caller_address(dvn, admin);
164
+ dispatcher.execute(execute_params.clone());
165
+
166
+ // Check that the config was set correctly
167
+ assert(dispatcher.get_dst_config(dst_eid) == config, 'Config should be set');
168
+ dispatcher.set_dst_config(array![Default::default()]);
169
+
170
+ stop_cheat_caller_address(dvn);
171
+ }
172
+ }
173
+
174
+ #[test]
175
+ #[fuzzer(runs: 10)]
176
+ fn should_skip_if_vid_is_invalid(
177
+ role_admin: RoleAdmin,
178
+ admin: ContractAddress,
179
+ vid: u32,
180
+ dst_eid: Eid,
181
+ config: DstConfig,
182
+ key_pair_1: KeyPair,
183
+ key_pair_2: KeyPair,
184
+ expiry: Expiry,
185
+ ) {
186
+ let dst_eid = dst_eid.eid;
187
+ let role_admin = role_admin.address;
188
+ let expiration: u256 = expiry.expiry.into();
189
+
190
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
191
+ let DvnDeploy {
192
+ dvn, dispatcher, ..,
193
+ } =
194
+ deploy_dvn_with_additional_roles(
195
+ array![].span(), vid, signers, role_admin, array![admin].span(),
196
+ );
197
+ let set_dst_config_params = array![SetDstConfigParams { dst_eid, config }];
198
+
199
+ let mut serialized_config = array![];
200
+ set_dst_config_params.serialize(ref serialized_config);
201
+
202
+ let call_data = Call {
203
+ to: dvn, selector: selector!("set_dst_config"), calldata: serialized_config.into(),
204
+ };
205
+
206
+ // Use an invalid vid
207
+ let invalid_vid = vid + 1;
208
+ let hash = dispatcher.hash_call_data(invalid_vid, call_data, expiration);
209
+
210
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
211
+ let execute_params = array![
212
+ ExecuteParam { vid: invalid_vid, call_data, expiration, signatures: signatures.into() },
213
+ ];
214
+
215
+ // Execute with the given params
216
+ // Caller has admin role
217
+ start_cheat_caller_address(dvn, admin);
218
+ dispatcher.execute(execute_params);
219
+ stop_cheat_caller_address(dvn);
220
+
221
+ // Check that the config was not set
222
+ assert(dispatcher.get_dst_config(dst_eid) == Default::default(), 'Config should not be set');
223
+ }
224
+
225
+ #[test]
226
+ #[fuzzer(runs: 10)]
227
+ fn should_skip_if_expired(
228
+ role_admin: RoleAdmin,
229
+ admins: ContractAddressArrayList,
230
+ vid: u32,
231
+ dst_eid: Eid,
232
+ config: DstConfig,
233
+ key_pair_1: KeyPair,
234
+ key_pair_2: KeyPair,
235
+ expiry: Expiry,
236
+ ) {
237
+ let dst_eid = dst_eid.eid;
238
+ let role_admin = role_admin.address;
239
+ let expiration = expiry.expiry;
240
+
241
+ let signers: Array<EthAddress> = array![
242
+ key_pair_1.public_address.clone().into(), key_pair_2.public_address.clone().into(),
243
+ ];
244
+ let DvnDeploy {
245
+ dvn, dispatcher, ..,
246
+ } =
247
+ deploy_dvn_with_additional_roles(
248
+ array![].span(), vid, signers, role_admin, admins.arr.span(),
249
+ );
250
+
251
+ let set_dst_config_params = array![SetDstConfigParams { dst_eid, config }];
252
+ let mut serialized_config = array![];
253
+ set_dst_config_params.serialize(ref serialized_config);
254
+
255
+ let call_data = Call {
256
+ to: dvn, selector: selector!("set_dst_config"), calldata: serialized_config.into(),
257
+ };
258
+
259
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration.into());
260
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
261
+ let execute_params = array![
262
+ ExecuteParam {
263
+ vid, call_data, expiration: expiration.into(), signatures: signatures.into(),
264
+ },
265
+ ];
266
+
267
+ // Set the block timestamp to be past expiration
268
+ start_cheat_block_timestamp(dvn, expiration + 1);
269
+
270
+ // Execute with the given params
271
+ for admin in admins.arr {
272
+ // Caller has admin role
273
+ start_cheat_caller_address(dvn, admin);
274
+ dispatcher.execute(execute_params.clone());
275
+ stop_cheat_caller_address(dvn);
276
+
277
+ // Check that the config was not set
278
+ assert(
279
+ dispatcher.get_dst_config(dst_eid) == Default::default(), 'Config should not be set',
280
+ );
281
+ }
282
+
283
+ stop_cheat_block_timestamp(dvn);
284
+ }
285
+
286
+ #[test]
287
+ #[fuzzer(runs: 10)]
288
+ fn should_emit_verify_signatures_failed(
289
+ role_admin: RoleAdmin,
290
+ admin: ContractAddress,
291
+ vid: u32,
292
+ key_pair_1: KeyPair,
293
+ key_pair_2: KeyPair,
294
+ key_pair_3: KeyPair,
295
+ expiry: Expiry,
296
+ ) {
297
+ let role_admin = role_admin.address;
298
+ let expiration: u256 = expiry.expiry.into();
299
+
300
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
301
+ let DvnDeploy {
302
+ dvn, dispatcher, ..,
303
+ } =
304
+ deploy_dvn_with_additional_roles(
305
+ array![].span(), vid, signers, role_admin, array![admin].span(),
306
+ );
307
+
308
+ let call_data = Call {
309
+ to: dvn, selector: selector!("set_dst_config"), calldata: array![].into(),
310
+ };
311
+
312
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
313
+ let signatures = array![sign_for_test_k1(key_pair_3.private_key, hash.into(), 3)];
314
+
315
+ let execute_params = array![
316
+ ExecuteParam { vid, call_data, expiration, signatures: signatures.into() },
317
+ ];
318
+
319
+ let mut spy = spy_events();
320
+
321
+ // Execute with the given params
322
+ // Caller has admin role
323
+ start_cheat_caller_address(dvn, admin);
324
+ dispatcher.execute(execute_params);
325
+ stop_cheat_caller_address(dvn);
326
+
327
+ // Check that the VerifySignaturesFailed event was emitted
328
+ spy
329
+ .assert_emitted(
330
+ @array![
331
+ (
332
+ dvn,
333
+ Dvn::Event::VerifySignaturesFailed(
334
+ events::VerifySignaturesFailed { error: err_signature_error() },
335
+ ),
336
+ ),
337
+ ],
338
+ );
339
+ }
340
+
341
+ #[test]
342
+ #[fuzzer(runs: 10)]
343
+ fn should_emit_hash_already_used(
344
+ role_admin: RoleAdmin,
345
+ admin: ContractAddress,
346
+ vid: u32,
347
+ dst_eid: Eid,
348
+ config: DstConfig,
349
+ key_pair_1: KeyPair,
350
+ key_pair_2: KeyPair,
351
+ expiry: Expiry,
352
+ ) {
353
+ let dst_eid = dst_eid.eid;
354
+ let role_admin = role_admin.address;
355
+ let expiration: u256 = expiry.expiry.into();
356
+
357
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
358
+ let DvnDeploy {
359
+ dvn, dispatcher, ..,
360
+ } =
361
+ deploy_dvn_with_additional_roles(
362
+ array![].span(), vid, signers, role_admin, array![admin].span(),
363
+ );
364
+
365
+ let set_dst_config_params = array![SetDstConfigParams { dst_eid, config }];
366
+ let mut serialized_config = array![];
367
+ set_dst_config_params.serialize(ref serialized_config);
368
+
369
+ let call_data = Call {
370
+ to: dvn, selector: selector!("set_dst_config"), calldata: serialized_config.into(),
371
+ };
372
+
373
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
374
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
375
+ let execute_param = ExecuteParam { vid, call_data, expiration, signatures: signatures.into() };
376
+
377
+ let mut spy = spy_events();
378
+
379
+ // Execute the same call twice
380
+ // Caller has admin role
381
+ start_cheat_caller_address(dvn, admin);
382
+ dispatcher.execute(array![execute_param.clone(), execute_param.clone()]);
383
+ stop_cheat_caller_address(dvn);
384
+
385
+ // Check that the HashAlreadyUsed event was emitted
386
+ spy
387
+ .assert_emitted(
388
+ @array![
389
+ (dvn, Dvn::Event::HashAlreadyUsed(events::HashAlreadyUsed { execute_param, hash })),
390
+ ],
391
+ );
392
+ }
393
+
394
+ ////////////////////
395
+ // Multisig tests //
396
+ ////////////////////
397
+
398
+ #[test]
399
+ #[fuzzer(runs: 10)]
400
+ fn mutlisig_set_signer_should_succeed_on_valid_signer(
401
+ role_admin: RoleAdmin,
402
+ admin: ContractAddress,
403
+ new_signer: EthAddress,
404
+ vid: u32,
405
+ key_pair_1: KeyPair,
406
+ key_pair_2: KeyPair,
407
+ expiry: Expiry,
408
+ ) {
409
+ let role_admin = role_admin.address;
410
+ let expiration: u256 = expiry.expiry.into();
411
+
412
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
413
+ let DvnDeploy {
414
+ dvn, dispatcher, ..,
415
+ } =
416
+ deploy_dvn_with_additional_roles(
417
+ array![].span(), vid, signers, role_admin, array![admin].span(),
418
+ );
419
+
420
+ // Serialize calldata
421
+ let mut serialized_calldata = array![];
422
+ let active = true;
423
+
424
+ new_signer.serialize(ref serialized_calldata);
425
+ active.serialize(ref serialized_calldata);
426
+
427
+ let call_data = Call {
428
+ to: dvn, selector: selector!("set_signer"), calldata: serialized_calldata.into(),
429
+ };
430
+
431
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
432
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
433
+ let execute_params = array![
434
+ ExecuteParam { vid, call_data, expiration, signatures: signatures.into() },
435
+ ];
436
+
437
+ let mut spy = spy_events();
438
+
439
+ // Execute with the given params
440
+ // Caller must be an admin for only the first call to satisfy the permissions of execute
441
+ // Since upgrade is permissioned by multisig, we need that call to come from the dvn contract
442
+ cheat_caller_address_once(dvn, admin);
443
+ dispatcher.execute(execute_params);
444
+
445
+ // Check that the signer was set
446
+ let multisig_dispatcher = IMultisigDispatcher { contract_address: dvn };
447
+ assert(multisig_dispatcher.is_signer(new_signer), 'Signer should be set');
448
+
449
+ // Check that the SignerSet event was emitted
450
+ spy
451
+ .assert_emitted(
452
+ @array![
453
+ (
454
+ dvn,
455
+ Dvn::Event::MultisigEvent(
456
+ MultisigComponent::Event::SignerSet(
457
+ SignerSet { signer: new_signer, active },
458
+ ),
459
+ ),
460
+ ),
461
+ ],
462
+ );
463
+ }
464
+
465
+ // This test ensures that setting the zero address as a signer fails with the expected error
466
+ // Can't use assert_panic_with_error because it doesn't work with syscall errors
467
+ #[test]
468
+ #[fuzzer(runs: 10)]
469
+ fn multisig_set_signer_should_fail_on_invalid_signer(
470
+ role_admin: RoleAdmin,
471
+ admin: ContractAddress,
472
+ vid: u32,
473
+ key_pair_1: KeyPair,
474
+ key_pair_2: KeyPair,
475
+ expiry: Expiry,
476
+ ) {
477
+ let role_admin = role_admin.address;
478
+ let expiration: u256 = expiry.expiry.into();
479
+
480
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
481
+ let DvnDeploy {
482
+ dvn, dispatcher, ..,
483
+ } =
484
+ deploy_dvn_with_additional_roles(
485
+ array![].span(), vid, signers, role_admin, array![admin].span(),
486
+ );
487
+
488
+ let mut serialized_calldata = array![];
489
+ let signer_0 = ZERO_ADDRESS;
490
+ let active = true;
491
+ signer_0.serialize(ref serialized_calldata);
492
+ active.serialize(ref serialized_calldata);
493
+
494
+ let call_data = Call {
495
+ to: dvn, selector: selector!("set_signer"), calldata: serialized_calldata.into(),
496
+ };
497
+
498
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
499
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
500
+ let execute_params = array![
501
+ ExecuteParam { vid, call_data, expiration, signatures: signatures.into() },
502
+ ];
503
+
504
+ let mut spy = spy_events();
505
+
506
+ // Attempt to execute with the given params
507
+ // Caller must be an admin for only the first call to satisfy the permissions of execute
508
+ // Since upgrade is permissioned by multisig, we need that call to come from the dvn contract
509
+ cheat_caller_address_once(dvn, admin);
510
+ dispatcher.execute(execute_params);
511
+
512
+ let event = spy.get_events();
513
+
514
+ // TODO(Levi): find a way to check that it is execute failed emitted
515
+ // this happens because current event returns array of of internal error
516
+ assert(event.events.len() == 1, 'ExecuteFailed not emitted');
517
+ }
518
+
519
+ #[test]
520
+ #[fuzzer(runs: 10)]
521
+ fn multisig_set_threshold_should_succeed_when_valid(
522
+ role_admin: RoleAdmin,
523
+ admin: ContractAddress,
524
+ vid: u32,
525
+ key_pair_1: KeyPair,
526
+ key_pair_2: KeyPair,
527
+ expiry: Expiry,
528
+ ) {
529
+ let role_admin = role_admin.address;
530
+ let expiration: u256 = expiry.expiry.into();
531
+
532
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
533
+ let DvnDeploy {
534
+ dvn, dispatcher, ..,
535
+ } =
536
+ deploy_dvn_with_additional_roles(
537
+ array![].span(), vid, signers, role_admin, array![admin].span(),
538
+ );
539
+
540
+ // This is the only valid threshold for 2 signers
541
+ let threshold = 1;
542
+
543
+ // Serialize calldata
544
+ let mut serialized_calldata = array![];
545
+ threshold.serialize(ref serialized_calldata);
546
+
547
+ let call_data = Call {
548
+ to: dvn, selector: selector!("set_threshold"), calldata: serialized_calldata.into(),
549
+ };
550
+
551
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
552
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
553
+ let execute_params = array![
554
+ ExecuteParam { vid, call_data, expiration, signatures: signatures.into() },
555
+ ];
556
+
557
+ let mut spy = spy_events();
558
+
559
+ // Execute with the given params
560
+ // Caller must be an admin for only the first call to satisfy the permissions of execute
561
+ // Since upgrade is permissioned by multisig, we need that call to come from the dvn contract
562
+ cheat_caller_address_once(dvn, admin);
563
+ dispatcher.execute(execute_params);
564
+
565
+ // Check that the threshold was set
566
+ let multisig_dispatcher = IMultisigDispatcher { contract_address: dvn };
567
+ assert(multisig_dispatcher.get_threshold() == threshold, 'Threshold should be set');
568
+
569
+ // Check that the ThresholdSet event was emitted
570
+ spy
571
+ .assert_emitted(
572
+ @array![
573
+ (
574
+ dvn,
575
+ Dvn::Event::MultisigEvent(
576
+ MultisigComponent::Event::ThresholdSet(ThresholdSet { threshold }),
577
+ ),
578
+ ),
579
+ ],
580
+ );
581
+ }
582
+
583
+ #[test]
584
+ #[fuzzer(runs: 10)]
585
+ fn multisig_set_threshold_should_fail_when_invalid(
586
+ role_admin: RoleAdmin,
587
+ admin: ContractAddress,
588
+ vid: u32,
589
+ key_pair_1: KeyPair,
590
+ key_pair_2: KeyPair,
591
+ expiry: Expiry,
592
+ ) {
593
+ let role_admin = role_admin.address;
594
+ let expiration: u256 = expiry.expiry.into();
595
+
596
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
597
+ let DvnDeploy {
598
+ dvn, dispatcher, ..,
599
+ } =
600
+ deploy_dvn_with_additional_roles(
601
+ array![].span(), vid, signers, role_admin, array![admin].span(),
602
+ );
603
+
604
+ // Serialize calldata
605
+ let threshold = 0;
606
+ let mut serialized_calldata = array![];
607
+ threshold.serialize(ref serialized_calldata);
608
+
609
+ let call_data = Call {
610
+ to: dvn, selector: selector!("set_threshold"), calldata: serialized_calldata.into(),
611
+ };
612
+
613
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
614
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
615
+ let execute_params = array![
616
+ ExecuteParam { vid, call_data, expiration, signatures: signatures.into() },
617
+ ];
618
+
619
+ let mut spy = spy_events();
620
+
621
+ // Attempt to execute with the given params
622
+ // Caller must be an admin for only the first call to satisfy the permissions of execute
623
+ // Since upgrade is permissioned by multisig, we need that call to come from the dvn contract
624
+ cheat_caller_address_once(dvn, admin);
625
+ dispatcher.execute(execute_params);
626
+
627
+ let event = spy.get_events();
628
+
629
+ // TODO(Levi): find a way to check that it is execute failed emitted
630
+ // this happens because current event returns array of of internal error
631
+ assert(event.events.len() == 1, 'ExecuteFailed not emitted');
632
+ }
633
+
634
+ ///////////////////
635
+ // Upgrade tests //
636
+ ///////////////////
637
+
638
+ #[test]
639
+ #[fuzzer(runs: 10)]
640
+ fn upgrade_succeeds(role_admin: RoleAdmin, vid: u32, key_pair_1: KeyPair, key_pair_2: KeyPair) {
641
+ let role_admin = role_admin.address;
642
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
643
+ let DvnDeploy {
644
+ dvn, dispatcher, ..,
645
+ } =
646
+ deploy_dvn_with_additional_roles(
647
+ array![].span(), vid, signers, role_admin, array![].span(),
648
+ );
649
+
650
+ let new_class_hash = declare("MockBaseWorker").unwrap().contract_class().class_hash;
651
+
652
+ // Upgrade
653
+ start_cheat_caller_address(dvn, dvn);
654
+ dispatcher.upgrade(*new_class_hash);
655
+ stop_cheat_caller_address(dvn);
656
+
657
+ // Check that the contract was upgraded
658
+ assert(get_class_hash(dvn) == *new_class_hash, 'Upgrade should succeed');
659
+ }
660
+
661
+ #[test]
662
+ #[fuzzer(runs: 10)]
663
+ fn upgrade_via_execute_succeeds(
664
+ role_admin: RoleAdmin,
665
+ admin: ContractAddress,
666
+ vid: u32,
667
+ key_pair_1: KeyPair,
668
+ key_pair_2: KeyPair,
669
+ expiry: Expiry,
670
+ ) {
671
+ let role_admin = role_admin.address;
672
+ let expiration: u256 = expiry.expiry.into();
673
+
674
+ let signers = array![key_pair_1.public_address.clone(), key_pair_2.public_address.clone()];
675
+ let DvnDeploy {
676
+ dvn, dispatcher, ..,
677
+ } =
678
+ deploy_dvn_with_additional_roles(
679
+ array![].span(), vid, signers, role_admin, array![admin].span(),
680
+ );
681
+
682
+ let new_class_hash = declare("MockBaseWorker").unwrap().contract_class().class_hash;
683
+
684
+ let mut calldata = array![];
685
+ new_class_hash.serialize(ref calldata);
686
+
687
+ let call_data = Call { to: dvn, selector: selector!("upgrade"), calldata: calldata.into() };
688
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
689
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
690
+
691
+ let execute_params = array![
692
+ ExecuteParam { vid, call_data, expiration, signatures: signatures.into() },
693
+ ];
694
+
695
+ // Execute with the given params
696
+ // Caller must be an admin for only the first call to satisfy the permissions of execute
697
+ // Since upgrade is permissioned by multisig, we need that call to come from the dvn contract
698
+ cheat_caller_address_once(dvn, admin);
699
+ dispatcher.execute(execute_params);
700
+
701
+ // Check that the contract was upgraded
702
+ assert(get_class_hash(dvn) == *new_class_hash, 'Upgrade should succeed');
703
+ }
704
+
705
+ #[test]
706
+ #[fuzzer(runs: 10)]
707
+ #[feature("safe_dispatcher")]
708
+ fn upgrade_fails_when_not_multisig(role_admin: ContractAddress, vid: u32) {
709
+ let DvnDeploy {
710
+ safe_dispatcher, ..,
711
+ } = deploy_dvn(array![].span(), vid, role_admin, array![].span());
712
+ let new_class_hash = declare("MockBaseWorker").unwrap().contract_class().class_hash;
713
+ let res = safe_dispatcher.upgrade(*new_class_hash);
714
+
715
+ // Check that the upgrade failed
716
+ assert_panic_with_error(res, err_only_multisig());
717
+ }
718
+
719
+ #[test]
720
+ #[fuzzer(runs: 10)]
721
+ #[feature("safe_dispatcher")]
722
+ fn upgrade_and_call_succeeds(role_admin: RoleAdmin, admin: ContractAddress, vid: u32) {
723
+ let role_admin = role_admin.address;
724
+ let DvnDeploy {
725
+ dvn, dispatcher, ..,
726
+ } = deploy_dvn(array![].span(), vid, role_admin, array![admin].span());
727
+
728
+ // Deploy mock DVN contract
729
+ let new_class_hash = declare("MockDVN").unwrap().contract_class().class_hash;
730
+
731
+ // Upgrade and call from self
732
+ start_cheat_caller_address(dvn, dvn);
733
+ let mut serialized_res = dispatcher
734
+ .upgrade_and_call(
735
+ *new_class_hash, selector!("get_dst_config"), array![1_u32.into()].span(),
736
+ );
737
+ stop_cheat_caller_address(dvn);
738
+
739
+ // Check that the function was called correctly
740
+ let res: DstConfig = Serde::deserialize(ref serialized_res).unwrap();
741
+ assert(res == MockDVN::DST_CONFIG_2, 'Function should be called');
742
+
743
+ // Check that the contract was upgraded
744
+ assert(get_class_hash(dvn) == *new_class_hash, 'Upgrade should succeed');
745
+ }
746
+
747
+ #[test]
748
+ #[fuzzer(runs: 10)]
749
+ #[feature("safe_dispatcher")]
750
+ fn upgrade_and_call_fails_when_not_multisig(role_admin: ContractAddress, vid: u32) {
751
+ let DvnDeploy {
752
+ safe_dispatcher, ..,
753
+ } = deploy_dvn(array![].span(), vid, role_admin, array![].span());
754
+ let new_class_hash = declare("MockBaseWorker").unwrap().contract_class().class_hash;
755
+ let res = safe_dispatcher.upgrade_and_call(*new_class_hash, 0, array![].span());
756
+
757
+ // Check that the upgrade failed
758
+ assert_panic_with_error(res, err_only_multisig());
759
+ }
760
+
761
+ ///////////////////////////////
762
+ // Quorum change admin tests //
763
+ ///////////////////////////////
764
+
765
+ #[test]
766
+ #[fuzzer(runs: 10)]
767
+ fn quorum_should_change_admin(
768
+ role_admin: RoleAdmin,
769
+ new_admin: ContractAddress,
770
+ sender: ContractAddress,
771
+ vid: u32,
772
+ key_pair_1: KeyPair,
773
+ key_pair_2: KeyPair,
774
+ expiry: Expiry,
775
+ ) {
776
+ let role_admin = role_admin.address;
777
+ let expiration: u256 = expiry.expiry.into();
778
+
779
+ let signers: Array<EthAddress> = array![
780
+ key_pair_1.public_address.clone().into(), key_pair_2.public_address.clone().into(),
781
+ ];
782
+ let DvnDeploy {
783
+ dvn, dispatcher, access_control, ..,
784
+ } =
785
+ deploy_dvn_with_additional_roles(
786
+ array![].span(), vid, signers, role_admin, array![].span(),
787
+ );
788
+
789
+ // Serialize the new admin address
790
+ let mut new_admin_serialized = array![];
791
+ new_admin.serialize(ref new_admin_serialized);
792
+
793
+ let call_data = Call {
794
+ to: dvn, selector: Default::default(), calldata: new_admin_serialized.into(),
795
+ };
796
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
797
+
798
+ // Create the execute param
799
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
800
+ let param = ExecuteParam { vid, call_data, expiration, signatures: signatures.into() };
801
+
802
+ let mut spy = spy_events();
803
+
804
+ // Call the function
805
+ // Anyone can call this function, we need to know the caller address for the event assertion
806
+ start_cheat_caller_address(dvn, sender);
807
+ dispatcher.quorum_change_admin(param);
808
+ stop_cheat_caller_address(dvn);
809
+
810
+ // Check that the new admin has the admin role
811
+ assert!(access_control.has_role(ADMIN_ROLE, new_admin), "New admin should have admin role");
812
+
813
+ spy
814
+ .assert_emitted(
815
+ @array![
816
+ (
817
+ dvn,
818
+ Dvn::Event::AccessControlEvent(
819
+ AccessControlComponent::Event::RoleGranted(
820
+ AccessControlComponent::RoleGranted {
821
+ role: ADMIN_ROLE, account: new_admin, sender,
822
+ },
823
+ ),
824
+ ),
825
+ ),
826
+ ],
827
+ );
828
+ }
829
+
830
+ #[test]
831
+ #[fuzzer(runs: 10)]
832
+ #[feature("safe_dispatcher")]
833
+ fn quorum_should_fail_to_change_admin_if_expired(
834
+ role_admin: RoleAdmin,
835
+ new_admin: ContractAddress,
836
+ vid: u32,
837
+ key_pair_1: KeyPair,
838
+ key_pair_2: KeyPair,
839
+ expiry: Expiry,
840
+ ) {
841
+ let role_admin = role_admin.address;
842
+ let expiration: u256 = expiry.expiry.into();
843
+
844
+ let signers: Array<EthAddress> = array![
845
+ key_pair_1.public_address.clone().into(), key_pair_2.public_address.clone().into(),
846
+ ];
847
+ let DvnDeploy {
848
+ dvn, dispatcher, safe_dispatcher, access_control, ..,
849
+ } =
850
+ deploy_dvn_with_additional_roles(
851
+ array![].span(), vid, signers, role_admin, array![].span(),
852
+ );
853
+
854
+ // Serialize the new admin address
855
+ let mut new_admin_serialized = array![];
856
+ new_admin.serialize(ref new_admin_serialized);
857
+
858
+ // Create the call data & hash
859
+ let call_data = Call {
860
+ to: dvn, selector: Default::default(), calldata: new_admin_serialized.span(),
861
+ };
862
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
863
+
864
+ // Create the execute param
865
+ let signatures = sort_signatures(key_pair_1.clone(), key_pair_2.clone(), hash);
866
+ let param = ExecuteParam { vid, call_data, expiration, signatures: signatures.into() };
867
+
868
+ // Call the function outside of the expiration time
869
+ start_cheat_block_timestamp(dvn, (expiration + 1).try_into().unwrap());
870
+ let res = safe_dispatcher.quorum_change_admin(param);
871
+ stop_cheat_block_timestamp(dvn);
872
+
873
+ // Check that the admin is not changed because the instruction is expired
874
+ assert_panic_with_error(res, errors::err_instruction_expired());
875
+ assert!(
876
+ !access_control.has_role(ADMIN_ROLE, new_admin), "New admin should not have admin role",
877
+ );
878
+ }
879
+
880
+ #[test]
881
+ #[fuzzer(runs: 10)]
882
+ #[feature("safe_dispatcher")]
883
+ fn quorum_should_fail_to_change_admin_if_invalid_vid(
884
+ role_admin: RoleAdmin,
885
+ new_admin: ContractAddress,
886
+ vid: u32,
887
+ invalid_vid: u32,
888
+ key_pair_1: KeyPair,
889
+ key_pair_2: KeyPair,
890
+ expiry: Expiry,
891
+ ) {
892
+ // Ensure that vid and invalid_vid are different
893
+ if vid == invalid_vid {
894
+ return;
895
+ }
896
+
897
+ let role_admin = role_admin.address;
898
+ let expiration: u256 = expiry.expiry.into();
899
+
900
+ let signers: Array<EthAddress> = array![
901
+ key_pair_1.public_address.clone().into(), key_pair_2.public_address.clone().into(),
902
+ ];
903
+ let DvnDeploy {
904
+ dvn, dispatcher, safe_dispatcher, access_control, ..,
905
+ } =
906
+ deploy_dvn_with_additional_roles(
907
+ array![].span(), vid, signers, role_admin, array![].span(),
908
+ );
909
+
910
+ // Serialize the new admin address
911
+ let mut new_admin_serialized = array![];
912
+ new_admin.serialize(ref new_admin_serialized);
913
+
914
+ // Create the call data & hash
915
+ let call_data = Call {
916
+ to: dvn, selector: Default::default(), calldata: new_admin_serialized.span(),
917
+ };
918
+ let hash = dispatcher.hash_call_data(invalid_vid, call_data, expiration);
919
+
920
+ // Create the execute param
921
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
922
+ let param = ExecuteParam {
923
+ vid: invalid_vid, call_data, expiration, signatures: signatures.into(),
924
+ };
925
+
926
+ // Call the function with invalid VID
927
+ let res = safe_dispatcher.quorum_change_admin(param);
928
+
929
+ // Check that the admin is not changed because the VID is invalid
930
+ assert_panic_with_error(res, errors::err_invalid_vid(invalid_vid));
931
+ assert!(
932
+ !access_control.has_role(ADMIN_ROLE, new_admin), "New admin should not have admin role",
933
+ );
934
+ }
935
+
936
+ #[test]
937
+ #[fuzzer(runs: 10)]
938
+ #[feature("safe_dispatcher")]
939
+ fn quorum_should_fail_to_change_admin_if_invalid_target(
940
+ role_admin: RoleAdmin,
941
+ new_admin: ContractAddress,
942
+ vid: u32,
943
+ key_pair_1: KeyPair,
944
+ key_pair_2: KeyPair,
945
+ invalid_target: ContractAddress,
946
+ expiry: Expiry,
947
+ ) {
948
+ let role_admin = role_admin.address;
949
+ let expiration: u256 = expiry.expiry.into();
950
+
951
+ let signers: Array<EthAddress> = array![
952
+ key_pair_1.public_address.clone().into(), key_pair_2.public_address.clone().into(),
953
+ ];
954
+ let DvnDeploy {
955
+ dvn, dispatcher, safe_dispatcher, access_control, ..,
956
+ } =
957
+ deploy_dvn_with_additional_roles(
958
+ array![].span(), vid, signers, role_admin, array![].span(),
959
+ );
960
+
961
+ // Ensure that the invalid target is different from the DVN
962
+ if invalid_target == dvn {
963
+ return;
964
+ }
965
+
966
+ // Serialize the new admin address
967
+ let mut new_admin_serialized = array![];
968
+ new_admin.serialize(ref new_admin_serialized);
969
+
970
+ // Create the call data & hash
971
+ let call_data = Call {
972
+ to: invalid_target, selector: Default::default(), calldata: new_admin_serialized.span(),
973
+ };
974
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
975
+
976
+ // Create the execute param
977
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
978
+ let param = ExecuteParam { vid, call_data, expiration, signatures: signatures.into() };
979
+
980
+ // Call the function with invalid target
981
+ let res = safe_dispatcher.quorum_change_admin(param);
982
+
983
+ // Check that the admin is not changed because the target is invalid
984
+ assert_panic_with_error(res, errors::err_invalid_target(invalid_target));
985
+ assert!(
986
+ !access_control.has_role(ADMIN_ROLE, new_admin), "New admin should not have admin role",
987
+ );
988
+ }
989
+
990
+ #[test]
991
+ #[fuzzer(runs: 10)]
992
+ #[feature("safe_dispatcher")]
993
+ fn quorum_should_fail_to_change_admin_if_duplicated_hash(
994
+ role_admin: RoleAdmin,
995
+ admin: ContractAddress,
996
+ vid: u32,
997
+ key_pair_1: KeyPair,
998
+ key_pair_2: KeyPair,
999
+ expiry: Expiry,
1000
+ ) {
1001
+ let role_admin = role_admin.address;
1002
+ let expiration: u256 = expiry.expiry.into();
1003
+
1004
+ let signers: Array<EthAddress> = array![
1005
+ key_pair_1.public_address.clone().into(), key_pair_2.public_address.clone().into(),
1006
+ ];
1007
+ let DvnDeploy {
1008
+ dvn, dispatcher, safe_dispatcher, access_control, ..,
1009
+ } =
1010
+ deploy_dvn_with_additional_roles(
1011
+ array![].span(), vid, signers, role_admin, array![].span(),
1012
+ );
1013
+
1014
+ // Serialize the admin address
1015
+ let mut admin_serialized = array![];
1016
+ admin.serialize(ref admin_serialized);
1017
+
1018
+ // Create the call data & hash
1019
+ let call_data = Call {
1020
+ to: dvn, selector: Default::default(), calldata: admin_serialized.span(),
1021
+ };
1022
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
1023
+
1024
+ // Create the execute param
1025
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
1026
+ let param = ExecuteParam { vid, call_data, expiration, signatures: signatures.into() };
1027
+
1028
+ // Call the function for the first time
1029
+ dispatcher.quorum_change_admin(param.clone());
1030
+
1031
+ // Check that admin has the admin role
1032
+ assert!(access_control.has_role(ADMIN_ROLE, admin), "Admin should have admin role");
1033
+
1034
+ // Call the function again with the same param
1035
+ let res = safe_dispatcher.quorum_change_admin(param);
1036
+
1037
+ // Check that the function fails because the hash is duplicated
1038
+ assert_panic_with_error(res, errors::err_duplicated_hash(hash));
1039
+ }
1040
+
1041
+ #[test]
1042
+ #[fuzzer(runs: 10)]
1043
+ #[feature("safe_dispatcher")]
1044
+ fn quorum_should_fail_to_change_admin_if_invalid_calldata(
1045
+ role_admin: RoleAdmin,
1046
+ vid: u32,
1047
+ key_pair_1: KeyPair,
1048
+ key_pair_2: KeyPair,
1049
+ invalid_calldata: Felt252ArrayList,
1050
+ expiry: Expiry,
1051
+ ) {
1052
+ let invalid_calldata = invalid_calldata.arr;
1053
+ // Ensure that invalid_calldata is not a serialized contract address
1054
+ let mut serialized = invalid_calldata.span();
1055
+ let res: Option<ContractAddress> = Serde::deserialize(ref serialized);
1056
+ if res.is_some() {
1057
+ return;
1058
+ }
1059
+
1060
+ let role_admin = role_admin.address;
1061
+ let expiration: u256 = expiry.expiry.into();
1062
+
1063
+ let signers: Array<EthAddress> = array![
1064
+ key_pair_1.public_address.clone().into(), key_pair_2.public_address.clone().into(),
1065
+ ];
1066
+ let DvnDeploy {
1067
+ dvn, dispatcher, safe_dispatcher, ..,
1068
+ } =
1069
+ deploy_dvn_with_additional_roles(
1070
+ array![].span(), vid, signers, role_admin, array![].span(),
1071
+ );
1072
+
1073
+ // Create the call data & hash
1074
+ let call_data = Call {
1075
+ to: dvn, selector: Default::default(), calldata: invalid_calldata.span(),
1076
+ };
1077
+ let hash = dispatcher.hash_call_data(vid, call_data, expiration);
1078
+
1079
+ // Create the execute param
1080
+ let signatures = sort_signatures(key_pair_1, key_pair_2, hash);
1081
+ let param = ExecuteParam { vid, call_data, expiration, signatures: signatures.into() };
1082
+
1083
+ // Call the function with invalid calldata
1084
+ let res = safe_dispatcher.quorum_change_admin(param);
1085
+
1086
+ // Check that the function fails because the calldata is invalid
1087
+ assert_panic_with_error(res, errors::err_invalid_quorum_admin());
1088
+ }
1089
+
1090
+ //////////////////////////
1091
+ // Implementation tests //
1092
+ //////////////////////////
1093
+
1094
+ #[test]
1095
+ fn impl_layer_zero_worker_interface() {
1096
+ const VID: u32 = 1;
1097
+ let DvnDeploy { dvn, .. } = deploy_dvn(array![].span(), VID, ZERO_ADDRESS, array![].span());
1098
+
1099
+ /// Runtime check that the dvn implements the ILayerZeroWorker interface
1100
+ ILayerZeroWorkerDispatcher { contract_address: dvn };
1101
+ }