@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,1472 @@
1
+ //! Executor tests
2
+
3
+ use core::num::traits::Pow;
4
+ use layerzero::Origin;
5
+ use layerzero::common::constants::ZERO_ADDRESS;
6
+ use layerzero::endpoint::events as endpoint_events;
7
+ use layerzero::endpoint::messaging_composer::events::{ComposeDelivered, LzComposeAlert};
8
+ use layerzero::endpoint::messaging_composer::messaging_composer::MessagingComposerComponent;
9
+ use layerzero::workers::access_control::{ADMIN_ROLE, DEFAULT_ADMIN_ROLE, MESSAGE_LIB_ROLE};
10
+ use layerzero::workers::base::interface::IWorkerBaseDispatcherTrait;
11
+ use layerzero::workers::executor::errors;
12
+ use layerzero::workers::executor::events::NativeDropApplied;
13
+ use layerzero::workers::executor::executor::Executor;
14
+ use layerzero::workers::executor::interface::{
15
+ IExecutorDispatcherTrait, IExecutorSafeDispatcherTrait,
16
+ };
17
+ use layerzero::workers::executor::structs::{DstConfig, NativeDropParams, SetDstConfigParams};
18
+ use layerzero::workers::interface::{
19
+ ILayerZeroWorkerDispatcher, ILayerZeroWorkerDispatcherTrait,
20
+ ILayerZeroWorkerSafeDispatcherTrait,
21
+ };
22
+ use layerzero::workers::price_feed::structs::GetFeeResponse;
23
+ use openzeppelin::access::accesscontrol::AccessControlComponent::Errors::MISSING_ROLE;
24
+ use openzeppelin::access::accesscontrol::interface::IAccessControlDispatcherTrait;
25
+ use openzeppelin::access::ownable::OwnableComponent;
26
+ use openzeppelin::token::erc20::interface::IERC20DispatcherTrait;
27
+ use snforge_std::{
28
+ DeclareResultTrait, EventSpyAssertionsTrait, EventSpyTrait, IsEmitted, declare, get_class_hash,
29
+ spy_events, start_cheat_caller_address, start_mock_call, stop_cheat_caller_address,
30
+ stop_mock_call,
31
+ };
32
+ use starknet::ContractAddress;
33
+ use starkware_utils_testing::test_utils::{
34
+ assert_panic_with_error, assert_panic_with_felt_error, cheat_caller_address_once,
35
+ };
36
+ use crate::endpoint::utils::{
37
+ EndpointMock, MessagingComposerMock, deploy_mock_endpoint, deploy_mock_messaging_composer,
38
+ };
39
+ use crate::fuzzable::contract_address::{
40
+ ContractAddressArrayList, FuzzableContractAddress, FuzzableContractAddresses,
41
+ };
42
+ use crate::fuzzable::dst_config::FuzzableExecutorDstConfig;
43
+ use crate::fuzzable::eid::{Eid, FuzzableEid};
44
+ use crate::fuzzable::origin::FuzzableOrigin;
45
+ use crate::fuzzable::role_admin::{FuzzableRoleAdmin, RoleAdmin};
46
+ use crate::mocks::endpoint::MockEndpoint;
47
+ use crate::mocks::endpoint::MockEndpoint::{
48
+ MockEndpointHelpersDispatcher, MockEndpointHelpersDispatcherTrait,
49
+ };
50
+ use crate::mocks::messaging_composer::MockMessagingComposer;
51
+ use crate::mocks::messaging_composer::MockMessagingComposer::MockMessagingComposerHelpersDispatcherTrait;
52
+ use crate::mocks::workers::executor::executor::MockExecutor;
53
+ use crate::workers::executor::utils::{
54
+ EXECUTOR_OWNER, ExecutorFeeLibTest, ExecutorMock, ExecutorOptionBytes, ExecutorTest,
55
+ create_mock_compose_params, create_mock_execute_params, create_mock_quote_params,
56
+ deploy_executor, deploy_executor_fee_lib, deploy_mock_executor, serialize_executor_options,
57
+ serialize_lz_receive_option,
58
+ };
59
+
60
+ //////////////////////////
61
+ // Access control tests //
62
+ //////////////////////////
63
+
64
+ /// Initial roles are set correctly
65
+ #[test]
66
+ #[fuzzer(runs: 10)]
67
+ fn sets_initial_roles(
68
+ endpoint_owner: ContractAddress,
69
+ eid: Eid,
70
+ role_admin: RoleAdmin,
71
+ price_feed: ContractAddress,
72
+ message_libs: ContractAddressArrayList,
73
+ admins: ContractAddressArrayList,
74
+ token_owner: ContractAddress,
75
+ ) {
76
+ let role_admin = role_admin.address;
77
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
78
+ let ExecutorTest {
79
+ access_control, ..,
80
+ } =
81
+ deploy_executor(
82
+ endpoint,
83
+ message_libs.arr.span(),
84
+ price_feed,
85
+ role_admin,
86
+ admins.arr.span(),
87
+ token_owner,
88
+ );
89
+
90
+ // Check that role admin was set correctly
91
+ assert(access_control.has_role(DEFAULT_ADMIN_ROLE, role_admin), 'Role admin should be set');
92
+ assert(!access_control.has_role(ADMIN_ROLE, role_admin), 'Role admin should not be admin');
93
+ assert!(
94
+ !access_control.has_role(MESSAGE_LIB_ROLE, role_admin), "Role admin should not be msg lib",
95
+ );
96
+
97
+ // Check that admin roles were set correctly
98
+ for admin in admins.arr {
99
+ assert(access_control.has_role(ADMIN_ROLE, admin), 'Admin role should be set');
100
+ assert(!access_control.has_role(MESSAGE_LIB_ROLE, admin), 'Admin should not be msg lib');
101
+ assert(
102
+ !access_control.has_role(DEFAULT_ADMIN_ROLE, admin), 'Admin should not be role admin',
103
+ );
104
+ }
105
+
106
+ // Check that message lib roles were set correctly
107
+ for msg_lib in message_libs.arr {
108
+ assert(access_control.has_role(MESSAGE_LIB_ROLE, msg_lib), 'Msg lib role should be set');
109
+ assert(!access_control.has_role(ADMIN_ROLE, msg_lib), 'Msg lib should not be admin');
110
+ assert!(
111
+ !access_control.has_role(DEFAULT_ADMIN_ROLE, msg_lib),
112
+ "Msg lib should not be role admin",
113
+ );
114
+ }
115
+ }
116
+
117
+ #[test]
118
+ #[fuzzer(runs: 10)]
119
+ fn should_set_dst_config_when_admin(
120
+ endpoint_owner: ContractAddress,
121
+ src_eid: Eid,
122
+ role_admin: RoleAdmin,
123
+ price_feed: ContractAddress,
124
+ admin: ContractAddress,
125
+ token_owner: ContractAddress,
126
+ dst_eid_1: Eid,
127
+ dst_eid_2: Eid,
128
+ dst_config_1: DstConfig,
129
+ dst_config_2: DstConfig,
130
+ ) {
131
+ let dst_eid_1 = dst_eid_1.eid;
132
+ let dst_eid_2 = dst_eid_2.eid;
133
+ let role_admin = role_admin.address;
134
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, src_eid.eid);
135
+ let ExecutorTest {
136
+ executor, dispatcher, ..,
137
+ } =
138
+ deploy_executor(
139
+ endpoint, array![].span(), price_feed, role_admin, array![admin].span(), token_owner,
140
+ );
141
+
142
+ // Set the dst configs
143
+ // Caller has the admin role
144
+ cheat_caller_address_once(executor, admin);
145
+ dispatcher
146
+ .set_dst_config(
147
+ array![
148
+ SetDstConfigParams { dst_eid: dst_eid_1, config: dst_config_1 },
149
+ SetDstConfigParams { dst_eid: dst_eid_2, config: dst_config_2 },
150
+ ],
151
+ );
152
+
153
+ // Check that the configs are set correctly
154
+ assert(dispatcher.get_dst_config(dst_eid_1) == dst_config_1, 'Config 1 not set correctly');
155
+ assert(dispatcher.get_dst_config(dst_eid_2) == dst_config_2, 'Config 2 not set correctly');
156
+ }
157
+
158
+ #[test]
159
+ #[fuzzer(runs: 10)]
160
+ fn should_fail_to_set_dst_config_when_not_admin(
161
+ endpoint_owner: ContractAddress,
162
+ src_eid: Eid,
163
+ role_admin: RoleAdmin,
164
+ price_feed: ContractAddress,
165
+ not_admin: ContractAddress,
166
+ dst_eid: Eid,
167
+ token_owner: ContractAddress,
168
+ config: DstConfig,
169
+ ) {
170
+ let dst_eid = dst_eid.eid;
171
+ let role_admin = role_admin.address;
172
+ let params = array![SetDstConfigParams { dst_eid, config }];
173
+
174
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, src_eid.eid);
175
+ let ExecutorTest {
176
+ executor, safe_dispatcher, access_control, ..,
177
+ } =
178
+ deploy_executor(
179
+ endpoint, array![].span(), price_feed, role_admin, array![].span(), token_owner,
180
+ );
181
+
182
+ // Check that not_admin is not an admin
183
+ assert(!access_control.has_role(ADMIN_ROLE, not_admin), 'Should not be an admin');
184
+
185
+ // Attempt to set dst config
186
+ // Caller does not have the admin role
187
+ cheat_caller_address_once(executor, not_admin);
188
+ let res = safe_dispatcher.set_dst_config(params.clone());
189
+
190
+ // Check that set dst config fails because the caller does not have the admin role
191
+ assert_panic_with_felt_error(res, MISSING_ROLE);
192
+
193
+ // Set the message lib role
194
+ // Caller is the role admin
195
+ start_cheat_caller_address(executor, role_admin);
196
+ access_control.grant_role(MESSAGE_LIB_ROLE, not_admin);
197
+ stop_cheat_caller_address(executor);
198
+
199
+ // Attempt to set dst config
200
+ // Caller has the message lib role
201
+ cheat_caller_address_once(executor, not_admin);
202
+ let res = safe_dispatcher.set_dst_config(params);
203
+
204
+ // Check that set dst config fails because the caller only has the message lib role
205
+ assert_panic_with_felt_error(res, MISSING_ROLE);
206
+ }
207
+
208
+ #[test]
209
+ #[fuzzer(runs: 10)]
210
+ fn should_fail_to_set_dst_config_when_message_lib(
211
+ endpoint_owner: ContractAddress,
212
+ src_eid: Eid,
213
+ role_admin: RoleAdmin,
214
+ price_feed: ContractAddress,
215
+ message_libs: ContractAddressArrayList,
216
+ dst_eid: Eid,
217
+ token_owner: ContractAddress,
218
+ config: DstConfig,
219
+ ) {
220
+ let dst_eid = dst_eid.eid;
221
+ let role_admin = role_admin.address;
222
+ let params = array![SetDstConfigParams { dst_eid, config }];
223
+
224
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, src_eid.eid);
225
+ let ExecutorTest {
226
+ executor, safe_dispatcher, ..,
227
+ } =
228
+ deploy_executor(
229
+ endpoint, message_libs.arr.span(), price_feed, role_admin, array![].span(), token_owner,
230
+ );
231
+
232
+ // Attempt to set dst config with each message lib
233
+ for msg_lib in message_libs.arr {
234
+ // Caller does not have the admin role
235
+ cheat_caller_address_once(executor, msg_lib);
236
+ let res = safe_dispatcher.set_dst_config(params.clone());
237
+
238
+ // Check that set dst config fails because the caller only has the message lib role
239
+ assert_panic_with_felt_error(res, MISSING_ROLE);
240
+ }
241
+ }
242
+
243
+ /////////////////
244
+ // Quote tests //
245
+ /////////////////
246
+
247
+ #[test]
248
+ #[fuzzer(runs: 10)]
249
+ fn should_fail_to_quote_when_eid_not_supported(
250
+ endpoint_owner: ContractAddress,
251
+ src_eid: Eid,
252
+ role_admin: RoleAdmin,
253
+ price_feed: ContractAddress,
254
+ admin: ContractAddress,
255
+ user: ContractAddress,
256
+ dst_eid: Eid,
257
+ token_owner: ContractAddress,
258
+ ) {
259
+ let role_admin = role_admin.address;
260
+
261
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, src_eid.eid);
262
+ let ExecutorTest {
263
+ executor, base_worker, safe_layer_zero_worker, ..,
264
+ } =
265
+ deploy_executor(
266
+ endpoint, array![].span(), price_feed, role_admin, array![admin].span(), token_owner,
267
+ );
268
+
269
+ // Deploy and set up fee lib
270
+ let ExecutorFeeLibTest { fee_lib, .. } = deploy_executor_fee_lib(dst_eid.eid, admin);
271
+
272
+ // Set the worker fee lib
273
+ start_cheat_caller_address(executor, admin);
274
+ base_worker.set_worker_fee_lib(fee_lib);
275
+ stop_cheat_caller_address(executor);
276
+
277
+ // Quote the job - should fail because EID is not supported (no dst config set)
278
+ // Caller can be any address
279
+ start_cheat_caller_address(executor, user);
280
+ let res = safe_layer_zero_worker
281
+ .quote(create_mock_quote_params(user, dst_eid.eid, Default::default()));
282
+ stop_cheat_caller_address(executor);
283
+
284
+ // Check that the quote fails because the EID is not supported
285
+ assert_panic_with_error(res, errors::err_eid_not_supported());
286
+ }
287
+
288
+
289
+ #[test]
290
+ #[fuzzer(runs: 10)]
291
+ fn should_fail_to_quote_when_price_feed_not_set(
292
+ endpoint_owner: ContractAddress,
293
+ src_eid: Eid,
294
+ role_admin: RoleAdmin,
295
+ admin: ContractAddress,
296
+ user: ContractAddress,
297
+ dst_eid: Eid,
298
+ token_owner: ContractAddress,
299
+ config: DstConfig,
300
+ ) {
301
+ let dst_eid = dst_eid.eid;
302
+ let role_admin = role_admin.address;
303
+ let mock_options = serialize_executor_options(
304
+ array![
305
+ ExecutorOptionBytes {
306
+ option_type: 1, option: serialize_lz_receive_option(100, Option::Some(50)),
307
+ },
308
+ ],
309
+ );
310
+
311
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, src_eid.eid);
312
+ let ExecutorTest {
313
+ executor, dispatcher, safe_layer_zero_worker, ..,
314
+ } =
315
+ deploy_executor(
316
+ endpoint, array![].span(), ZERO_ADDRESS, role_admin, array![admin].span(), token_owner,
317
+ );
318
+
319
+ // Set the dst config - do not set the price feed
320
+ // Caller has admin role
321
+ start_cheat_caller_address(executor, admin);
322
+ dispatcher.set_dst_config(array![SetDstConfigParams { dst_eid, config }]);
323
+ stop_cheat_caller_address(executor);
324
+
325
+ // Check that the quote fails because the price feed is not set
326
+ let res = safe_layer_zero_worker.quote(create_mock_quote_params(user, dst_eid, mock_options));
327
+ assert_panic_with_error(res, errors::err_price_feed_not_set());
328
+ }
329
+
330
+ #[test]
331
+ #[fuzzer(runs: 10)]
332
+ fn should_correctly_quote(
333
+ endpoint_owner: ContractAddress,
334
+ src_eid: Eid,
335
+ role_admin: RoleAdmin,
336
+ admin: ContractAddress,
337
+ user: ContractAddress,
338
+ price_feed: ContractAddress,
339
+ dst_eid: Eid,
340
+ token_owner: ContractAddress,
341
+ config: DstConfig,
342
+ ) {
343
+ let dst_eid = dst_eid.eid;
344
+ let role_admin = role_admin.address;
345
+
346
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, src_eid.eid);
347
+ let ExecutorTest {
348
+ executor, base_worker, dispatcher, layer_zero_worker, ..,
349
+ } =
350
+ deploy_executor(
351
+ endpoint, array![].span(), price_feed, role_admin, array![admin].span(), token_owner,
352
+ );
353
+
354
+ // User wants to send 0.01 ETH and specifies 50,000 gas for execution.
355
+ // 0.01 ETH = 10^16 wei
356
+ let lz_receive_value = 10_u128.pow(16);
357
+ let lz_receive_option = serialize_lz_receive_option(50000, Option::Some(lz_receive_value));
358
+ let mock_options = serialize_executor_options(
359
+ array![ExecutorOptionBytes { option_type: 1, option: lz_receive_option }],
360
+ );
361
+
362
+ // Let's assume ETH is the native token (18 decimals).
363
+ // Let's set a 10% premium (multiplier_bps = 11000).
364
+ // Let's set a floor margin of $1.50 USD.
365
+ let set_dst_config_params = SetDstConfigParams {
366
+ dst_eid,
367
+ config: DstConfig {
368
+ lz_receive_base_gas: 200000, // Base gas for a receive operation
369
+ multiplier_bps: 11000, // 110% -> 10% premium
370
+ floor_margin_usd: 1_500_000_000_000_000_000, // $1.50 with 18 decimals
371
+ native_cap: 10_u128.pow(18), // 1 ETH cap
372
+ lz_compose_base_gas: 0,
373
+ },
374
+ };
375
+
376
+ // Deploy and set up fee lib
377
+ let ExecutorFeeLibTest { fee_lib, .. } = deploy_executor_fee_lib(dst_eid, admin);
378
+
379
+ // Update the set_dst_config_params to use the v2 EID
380
+ let set_dst_config_params = SetDstConfigParams {
381
+ dst_eid, config: set_dst_config_params.config,
382
+ };
383
+
384
+ // Set the dst config, price feed, and worker fee lib
385
+ // Caller has admin role
386
+ start_cheat_caller_address(executor, admin);
387
+ dispatcher.set_dst_config(array![set_dst_config_params]);
388
+ base_worker.set_price_feed(price_feed);
389
+ base_worker.set_worker_fee_lib(fee_lib);
390
+ stop_cheat_caller_address(executor);
391
+
392
+ // Mock the price feed response
393
+ // total_gas = lz_receive_base_gas (200,000) + lz_receive_option gas (50,000) = 250,000.
394
+ // Let's say the price_feed determines this costs 0.00075 ETH.
395
+ let mock_gas_fee = 750_000_000_000_000; // 0.00075 ETH in wei
396
+ // 1 ETH = $3000. We send price with 18 decimals.
397
+ let native_price_usd = 3000_u128 * 10_u128.pow(18);
398
+ let mock_response = GetFeeResponse {
399
+ gas_fee: mock_gas_fee,
400
+ price_ratio: 1, // Source and dest chains use same-priced native token
401
+ price_ratio_denominator: 1,
402
+ native_price_usd,
403
+ };
404
+
405
+ start_mock_call(price_feed, selector!("estimate_fee_on_send"), mock_response);
406
+ let quote = layer_zero_worker.quote(create_mock_quote_params(user, dst_eid, mock_options));
407
+ stop_mock_call(price_feed, selector!("estimate_fee_on_send"));
408
+
409
+ // Expected fee calculation:
410
+ // 1. Gas Component
411
+ // multiplier = 11000 / 10000 = 1.1
412
+ // fee_with_multiplier = 0.00075 * 1.1 = 0.000825 ETH
413
+ // margin_in_native = ($1.5 * 10^18) / ($3000 * 10^18 per ETH) = 0.0005 ETH
414
+ // fee_with_margin = 0.00075 + 0.0005 = 0.00125 ETH
415
+ // gas_component = max(0.000825, 0.00125) = 0.00125 ETH
416
+ let gas_component = 1_250_000_000_000_000; // 0.00125 ETH in wei
417
+
418
+ // 2. Value Component
419
+ // total_value = 0.01 ETH from lz_receive_option
420
+ // converted_total_value = 0.01 ETH (since price_ratio is 1)
421
+ // value_component = 0.01 * 1.1 = 0.011 ETH
422
+ let value_component = 11_000_000_000_000_000; // 0.011 ETH in wei
423
+
424
+ // 3. Total Fee
425
+ // total_fee = 0.00125 + 0.011 = 0.01225 ETH
426
+ // Check that the quote is correct
427
+ assert(quote == gas_component + value_component, 'Quote should be expected fee');
428
+ }
429
+
430
+ ///////////////////
431
+ // Upgrade tests //
432
+ ///////////////////
433
+
434
+ #[test]
435
+ #[fuzzer(runs: 10)]
436
+ fn upgrade_succeeds(
437
+ endpoint_owner: ContractAddress,
438
+ eid: Eid,
439
+ role_admin: RoleAdmin,
440
+ price_feed: ContractAddress,
441
+ token_owner: ContractAddress,
442
+ ) {
443
+ let role_admin = role_admin.address;
444
+
445
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
446
+ let ExecutorTest {
447
+ executor, dispatcher, ..,
448
+ } =
449
+ deploy_executor(
450
+ endpoint, array![].span(), price_feed, role_admin, array![].span(), token_owner,
451
+ );
452
+ let new_class = declare("MockBaseWorker").unwrap().contract_class().class_hash;
453
+
454
+ // Upgrade the contract
455
+ // Caller is the owner
456
+ start_cheat_caller_address(executor, EXECUTOR_OWNER);
457
+ dispatcher.upgrade(*new_class);
458
+ stop_cheat_caller_address(executor);
459
+
460
+ // Check that the upgrade succeeds
461
+ assert(get_class_hash(executor) == *new_class, 'Upgrade should succeed');
462
+ }
463
+
464
+ #[test]
465
+ #[fuzzer(runs: 10)]
466
+ fn upgrade_fails_when_not_owner(
467
+ endpoint_owner: ContractAddress,
468
+ eid: Eid,
469
+ role_admin: RoleAdmin,
470
+ not_owner: ContractAddress,
471
+ price_feed: ContractAddress,
472
+ token_owner: ContractAddress,
473
+ ) {
474
+ // Ensure that not_owner is not the owner
475
+ if not_owner == EXECUTOR_OWNER {
476
+ return;
477
+ }
478
+
479
+ let role_admin = role_admin.address;
480
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
481
+ let ExecutorTest {
482
+ executor, safe_dispatcher, ..,
483
+ } =
484
+ deploy_executor(
485
+ endpoint, array![].span(), price_feed, role_admin, array![].span(), token_owner,
486
+ );
487
+ let new_class = declare("MockBaseWorker").unwrap().contract_class().class_hash;
488
+
489
+ // Attempt to upgrade the contract - role admin
490
+ // Caller is the role admin
491
+ start_cheat_caller_address(executor, role_admin);
492
+ let res = safe_dispatcher.upgrade(*new_class);
493
+ stop_cheat_caller_address(executor);
494
+
495
+ // Check that the upgrade fails because role_admin does not have the admin role
496
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
497
+
498
+ // Attempt to upgrade the contract - non-owner
499
+ // Caller is not the owner
500
+ start_cheat_caller_address(executor, not_owner);
501
+ let res = safe_dispatcher.upgrade(*new_class);
502
+ stop_cheat_caller_address(executor);
503
+
504
+ // Check that the upgrade fails because not_owner is not the owner
505
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
506
+ }
507
+
508
+ #[test]
509
+ #[fuzzer(runs: 10)]
510
+ fn upgrade_and_call_succeeds(
511
+ endpoint_owner: ContractAddress,
512
+ eid: Eid,
513
+ role_admin: RoleAdmin,
514
+ price_feed: ContractAddress,
515
+ token_owner: ContractAddress,
516
+ ) {
517
+ let role_admin = role_admin.address;
518
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
519
+ let ExecutorTest {
520
+ executor, dispatcher, ..,
521
+ } =
522
+ deploy_executor(
523
+ endpoint, array![].span(), price_feed, role_admin, array![].span(), token_owner,
524
+ );
525
+
526
+ let new_class_hash = declare("MockExecutor").unwrap().contract_class().class_hash;
527
+
528
+ // Upgrade and call
529
+ // Caller is the owner
530
+ start_cheat_caller_address(executor, EXECUTOR_OWNER);
531
+ let mut serialized_res = dispatcher
532
+ .upgrade_and_call(
533
+ *new_class_hash, selector!("get_dst_config"), array![0_u32.into()].span(),
534
+ );
535
+ stop_cheat_caller_address(executor);
536
+
537
+ // Check that the function was called correctly
538
+ let res: DstConfig = Serde::deserialize(ref serialized_res).unwrap();
539
+ assert(res == MockExecutor::DST_CONFIG, 'Function should be called');
540
+
541
+ // Check that the contract was upgraded
542
+ assert(get_class_hash(executor) == *new_class_hash, 'Upgrade should succeed');
543
+ }
544
+
545
+ #[test]
546
+ #[fuzzer(runs: 10)]
547
+ #[feature("safe_dispatcher")]
548
+ fn upgrade_and_call_fails_when_not_owner(
549
+ endpoint_owner: ContractAddress,
550
+ eid: Eid,
551
+ role_admin: RoleAdmin,
552
+ not_owner: ContractAddress,
553
+ price_feed: ContractAddress,
554
+ token_owner: ContractAddress,
555
+ ) {
556
+ // Ensure that not_owner is not the owner
557
+ if not_owner == EXECUTOR_OWNER {
558
+ return;
559
+ }
560
+
561
+ let role_admin = role_admin.address;
562
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
563
+ let ExecutorTest {
564
+ executor, safe_dispatcher, ..,
565
+ } =
566
+ deploy_executor(
567
+ endpoint, array![].span(), price_feed, role_admin, array![].span(), token_owner,
568
+ );
569
+
570
+ let new_class_hash = declare("MockExecutor").unwrap().contract_class().class_hash;
571
+
572
+ // Attempt to upgrade and call
573
+ // Caller is not the owner
574
+ start_cheat_caller_address(executor, not_owner);
575
+ let res = safe_dispatcher.upgrade_and_call(*new_class_hash, 0, array![].span());
576
+ stop_cheat_caller_address(executor);
577
+
578
+ // Check that the upgrade fails because the caller is not the owner
579
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
580
+ }
581
+
582
+ ///////////////////
583
+ // Execute tests //
584
+ ///////////////////
585
+
586
+ #[test]
587
+ #[fuzzer(runs: 10)]
588
+ fn execute_should_succeed_with_packet_delivered_event(
589
+ endpoint_owner: ContractAddress,
590
+ eid: Eid,
591
+ role_admin: RoleAdmin,
592
+ admin: ContractAddress,
593
+ receiver: ContractAddress,
594
+ ) {
595
+ let eid = eid.eid;
596
+
597
+ // Deploy contracts
598
+ let EndpointMock { endpoint, token, .. } = deploy_mock_endpoint(endpoint_owner, eid);
599
+ let ExecutorTest {
600
+ executor, dispatcher, ..,
601
+ } =
602
+ deploy_executor(
603
+ endpoint,
604
+ array![].span(),
605
+ token,
606
+ role_admin.address,
607
+ array![admin].span(),
608
+ endpoint_owner,
609
+ );
610
+
611
+ // ExecuteParams - values are not important because we're mocking the endpoint
612
+ let params = create_mock_execute_params(eid, receiver);
613
+ let origin = params.origin.clone();
614
+
615
+ let mut spy = spy_events();
616
+
617
+ // Execute
618
+ start_cheat_caller_address(executor, admin);
619
+ dispatcher.execute(params);
620
+ stop_cheat_caller_address(executor);
621
+
622
+ // Check that endpoint event was emitted
623
+ spy
624
+ .assert_emitted(
625
+ @array![
626
+ (
627
+ endpoint,
628
+ MockEndpoint::Event::PacketDelivered(
629
+ endpoint_events::PacketDelivered { origin, receiver },
630
+ ),
631
+ ),
632
+ ],
633
+ );
634
+ }
635
+
636
+ #[test]
637
+ #[fuzzer(runs: 10)]
638
+ fn execute_should_fail_with_alert_event(
639
+ endpoint_owner: ContractAddress,
640
+ eid: Eid,
641
+ role_admin: RoleAdmin,
642
+ admin: ContractAddress,
643
+ receiver: ContractAddress,
644
+ ) {
645
+ let eid = eid.eid;
646
+
647
+ // Deploy contracts
648
+ let EndpointMock { endpoint, token, .. } = deploy_mock_endpoint(endpoint_owner, eid);
649
+ let ExecutorTest {
650
+ executor, dispatcher, ..,
651
+ } =
652
+ deploy_executor(
653
+ endpoint,
654
+ array![].span(),
655
+ token,
656
+ role_admin.address,
657
+ array![admin].span(),
658
+ endpoint_owner,
659
+ );
660
+
661
+ // ExecuteParams - values are not important because we're mocking the endpoint
662
+ let params = create_mock_execute_params(eid, receiver);
663
+ let origin = params.origin.clone();
664
+
665
+ // Set the endpoint to fail on lz_receive
666
+ let mut endpoint_dispatcher = MockEndpointHelpersDispatcher { contract_address: endpoint };
667
+ endpoint_dispatcher.set_receive_should_fail(true);
668
+
669
+ let mut spy = spy_events();
670
+
671
+ // Execute
672
+ start_cheat_caller_address(executor, admin);
673
+ dispatcher.execute(params.clone());
674
+ stop_cheat_caller_address(executor);
675
+
676
+ // Check that endpoint event was emitted
677
+ spy
678
+ .assert_emitted(
679
+ @array![
680
+ (
681
+ endpoint,
682
+ MockEndpoint::Event::LzReceiveAlert(
683
+ endpoint_events::LzReceiveAlert {
684
+ origin,
685
+ executor,
686
+ receiver,
687
+ guid: params.guid,
688
+ gas: 0,
689
+ value: params.value,
690
+ message: params.message,
691
+ extra_data: params.extra_data,
692
+ reason: array!['Mock receive failed'],
693
+ },
694
+ ),
695
+ ),
696
+ ],
697
+ );
698
+ }
699
+
700
+ #[test]
701
+ #[fuzzer(runs: 10)]
702
+ fn execute_should_fail_when_not_admin(
703
+ role_admin: RoleAdmin,
704
+ endpoint_owner: ContractAddress,
705
+ not_admin: ContractAddress,
706
+ price_feed: ContractAddress,
707
+ token_owner: ContractAddress,
708
+ receiver: ContractAddress,
709
+ eid: Eid,
710
+ ) {
711
+ let eid = eid.eid;
712
+ let role_admin = role_admin.address;
713
+
714
+ // Deploy contracts
715
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid);
716
+ let ExecutorTest {
717
+ executor, safe_dispatcher, ..,
718
+ } =
719
+ deploy_executor(
720
+ endpoint, array![].span(), price_feed, role_admin, array![].span(), token_owner,
721
+ );
722
+
723
+ // ExecuteParams values are not important because we're mocking the endpoint
724
+ let params = create_mock_execute_params(eid, receiver);
725
+
726
+ // Attempt to execute
727
+ // Caller does not have admin role
728
+ start_cheat_caller_address(executor, not_admin);
729
+ let res = safe_dispatcher.execute(params);
730
+ stop_cheat_caller_address(executor);
731
+
732
+ // Check that the execute fails because the caller does not have the admin role
733
+ assert_panic_with_felt_error(res, MISSING_ROLE);
734
+ }
735
+
736
+ ///////////////////
737
+ // Compose tests //
738
+ ///////////////////
739
+
740
+ #[test]
741
+ #[fuzzer(runs: 10)]
742
+ fn compose_should_succeed_with_compose_delivered_event(
743
+ token: ContractAddress, sender: ContractAddress, receiver: ContractAddress,
744
+ ) {
745
+ // Deploy mock contracts
746
+ let MessagingComposerMock {
747
+ composer, dispatcher: composer_dispatcher, ..,
748
+ } = deploy_mock_messaging_composer(token);
749
+ let ExecutorMock {
750
+ dispatcher, ..,
751
+ } = deploy_mock_executor(ZERO_ADDRESS, ZERO_ADDRESS, composer);
752
+
753
+ // Set the messaging composer to be mock
754
+ composer_dispatcher.set_is_real(false);
755
+
756
+ // ComposeParams values are not important because we're mocking the endpoint
757
+ let params = create_mock_compose_params(sender, receiver);
758
+
759
+ let mut spy = spy_events();
760
+
761
+ // Compose
762
+ // Mock executor does not have access control
763
+ dispatcher.compose(params.clone());
764
+
765
+ // Check that compose delivered event was emitted
766
+ spy
767
+ .assert_emitted(
768
+ @array![
769
+ (
770
+ composer,
771
+ MockMessagingComposer::Event::MessagingComposerEvent(
772
+ MessagingComposerComponent::Event::ComposeDelivered(
773
+ ComposeDelivered {
774
+ from: params.sender,
775
+ to: params.receiver,
776
+ guid: params.guid,
777
+ index: params.index,
778
+ },
779
+ ),
780
+ ),
781
+ ),
782
+ ],
783
+ );
784
+ }
785
+
786
+ #[test]
787
+ #[fuzzer(runs: 10)]
788
+ fn compose_should_fail_with_lz_compose_alert_event(
789
+ token: ContractAddress, sender: ContractAddress, receiver: ContractAddress,
790
+ ) {
791
+ // Deploy mock contracts
792
+ let MessagingComposerMock {
793
+ composer, dispatcher: composer_dispatcher, ..,
794
+ } = deploy_mock_messaging_composer(token);
795
+ let ExecutorMock {
796
+ dispatcher, ..,
797
+ } = deploy_mock_executor(ZERO_ADDRESS, ZERO_ADDRESS, composer);
798
+
799
+ // Set the messaging composer to be mock and fail on lz_compose
800
+ composer_dispatcher.set_is_real(false);
801
+ composer_dispatcher.set_should_compose_fail(true);
802
+
803
+ // ComposeParams values are not important because we're mocking the endpoint
804
+ let params = create_mock_compose_params(sender, receiver);
805
+
806
+ let mut spy = spy_events();
807
+
808
+ // Compose
809
+ // Mock executor does not have access control
810
+ dispatcher.compose(params.clone());
811
+
812
+ // Check that compose alert event was emitted
813
+ spy
814
+ .assert_emitted(
815
+ @array![
816
+ (
817
+ composer,
818
+ MockMessagingComposer::Event::MessagingComposerEvent(
819
+ MessagingComposerComponent::Event::LzComposeAlert(
820
+ LzComposeAlert {
821
+ from: params.sender,
822
+ to: params.receiver,
823
+ executor: ZERO_ADDRESS,
824
+ guid: params.guid,
825
+ index: params.index,
826
+ gas: 0,
827
+ value: params.value,
828
+ message: params.message,
829
+ extra_data: params.extra_data,
830
+ reason: array!['MockComposer: lz_compose failed'],
831
+ },
832
+ ),
833
+ ),
834
+ ),
835
+ ],
836
+ );
837
+ }
838
+
839
+ #[test]
840
+ #[fuzzer(runs: 10)]
841
+ fn compose_should_fail_when_not_admin(
842
+ endpoint_owner: ContractAddress,
843
+ eid: Eid,
844
+ role_admin: RoleAdmin,
845
+ not_admin: ContractAddress,
846
+ token_owner: ContractAddress,
847
+ sender: ContractAddress,
848
+ receiver: ContractAddress,
849
+ ) {
850
+ let role_admin = role_admin.address;
851
+
852
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
853
+ let ExecutorTest {
854
+ executor, safe_dispatcher, ..,
855
+ } =
856
+ deploy_executor(
857
+ endpoint, array![].span(), ZERO_ADDRESS, role_admin, array![].span(), token_owner,
858
+ );
859
+
860
+ // ComposeParams values are not important because we're mocking the endpoint
861
+ let params = create_mock_compose_params(sender, receiver);
862
+
863
+ // Attempt to compose
864
+ // Caller does not have admin role
865
+ start_cheat_caller_address(executor, not_admin);
866
+ let res = safe_dispatcher.compose(params);
867
+ stop_cheat_caller_address(executor);
868
+
869
+ // Check that the compose fails because the caller does not have the admin role
870
+ assert_panic_with_felt_error(res, MISSING_ROLE);
871
+ }
872
+
873
+ ///////////////////////
874
+ // Native drop tests //
875
+ ///////////////////////
876
+
877
+ #[test]
878
+ #[fuzzer(runs: 10)]
879
+ fn native_drop_to_no_receiver(
880
+ endpoint_owner: ContractAddress,
881
+ eid: Eid,
882
+ role_admin: RoleAdmin,
883
+ admin: ContractAddress,
884
+ price_feed: ContractAddress,
885
+ token_owner: ContractAddress,
886
+ origin: Origin,
887
+ oapp: ContractAddress,
888
+ ) {
889
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
890
+ let ExecutorTest {
891
+ executor, dispatcher, ..,
892
+ } =
893
+ deploy_executor(
894
+ endpoint,
895
+ array![].span(),
896
+ price_feed,
897
+ role_admin.address,
898
+ array![admin].span(),
899
+ token_owner,
900
+ );
901
+
902
+ let mut spy = spy_events();
903
+
904
+ cheat_caller_address_once(executor, admin);
905
+ dispatcher.native_drop(origin.clone(), oapp, array![]);
906
+
907
+ // Check that native drop applied event was emitted
908
+ spy
909
+ .assert_emitted(
910
+ @array![
911
+ (
912
+ executor,
913
+ Executor::Event::NativeDropApplied(
914
+ NativeDropApplied {
915
+ origin,
916
+ dst_eid: eid.eid,
917
+ oapp,
918
+ native_drop_params: array![],
919
+ success: array![],
920
+ },
921
+ ),
922
+ ),
923
+ ],
924
+ );
925
+ }
926
+
927
+ #[test]
928
+ #[fuzzer(runs: 10)]
929
+ fn native_drop_to_single_receiver(
930
+ endpoint_owner: ContractAddress,
931
+ eid: Eid,
932
+ role_admin: RoleAdmin,
933
+ admin: ContractAddress,
934
+ price_feed: ContractAddress,
935
+ token_owner: ContractAddress,
936
+ origin: Origin,
937
+ oapp: ContractAddress,
938
+ token_receiver: ContractAddress,
939
+ token_amount: u8,
940
+ ) {
941
+ let token_amount = token_amount.into() + 1;
942
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
943
+ let ExecutorTest {
944
+ executor, dispatcher, token_dispatcher, ..,
945
+ } =
946
+ deploy_executor(
947
+ endpoint,
948
+ array![].span(),
949
+ price_feed,
950
+ role_admin.address,
951
+ array![admin].span(),
952
+ token_owner,
953
+ );
954
+
955
+ let mut spy = spy_events();
956
+
957
+ cheat_caller_address_once(executor, admin);
958
+ dispatcher
959
+ .native_drop(
960
+ origin.clone(),
961
+ oapp,
962
+ array![NativeDropParams { receiver: token_receiver, amount: token_amount }],
963
+ );
964
+
965
+ assert(token_dispatcher.balance_of(token_receiver) == token_amount, 'Invalid token amount');
966
+
967
+ // Check that native drop applied event was emitted
968
+ spy
969
+ .assert_emitted(
970
+ @array![
971
+ (
972
+ executor,
973
+ Executor::Event::NativeDropApplied(
974
+ NativeDropApplied {
975
+ origin,
976
+ dst_eid: eid.eid,
977
+ oapp,
978
+ native_drop_params: array![
979
+ NativeDropParams { receiver: token_receiver, amount: token_amount },
980
+ ],
981
+ success: array![true],
982
+ },
983
+ ),
984
+ ),
985
+ ],
986
+ );
987
+ }
988
+
989
+ #[test]
990
+ #[fuzzer(runs: 10)]
991
+ fn native_drop_to_two_receivers(
992
+ endpoint_owner: ContractAddress,
993
+ eid: Eid,
994
+ role_admin: RoleAdmin,
995
+ admin: ContractAddress,
996
+ price_feed: ContractAddress,
997
+ token_owner: ContractAddress,
998
+ origin: Origin,
999
+ oapp: ContractAddress,
1000
+ token_receiver_1: ContractAddress,
1001
+ token_receiver_2: ContractAddress,
1002
+ token_amount_1: u8,
1003
+ token_amount_2: u8,
1004
+ ) {
1005
+ let token_amount_1 = token_amount_1.into();
1006
+ let token_amount_2 = token_amount_2.into();
1007
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1008
+ let ExecutorTest {
1009
+ executor, dispatcher, token_dispatcher, ..,
1010
+ } =
1011
+ deploy_executor(
1012
+ endpoint,
1013
+ array![].span(),
1014
+ price_feed,
1015
+ role_admin.address,
1016
+ array![admin].span(),
1017
+ token_owner,
1018
+ );
1019
+
1020
+ let mut spy = spy_events();
1021
+
1022
+ cheat_caller_address_once(executor, admin);
1023
+ dispatcher
1024
+ .native_drop(
1025
+ origin.clone(),
1026
+ oapp,
1027
+ array![
1028
+ NativeDropParams { receiver: token_receiver_1, amount: token_amount_1 },
1029
+ NativeDropParams { receiver: token_receiver_2, amount: token_amount_2 },
1030
+ ],
1031
+ );
1032
+
1033
+ assert(token_dispatcher.balance_of(token_receiver_1) == token_amount_1, 'Invalid token amount');
1034
+ assert(token_dispatcher.balance_of(token_receiver_2) == token_amount_2, 'Invalid token amount');
1035
+
1036
+ spy
1037
+ .assert_emitted(
1038
+ @array![
1039
+ (
1040
+ executor,
1041
+ Executor::Event::NativeDropApplied(
1042
+ NativeDropApplied {
1043
+ origin,
1044
+ dst_eid: eid.eid,
1045
+ oapp,
1046
+ native_drop_params: array![
1047
+ NativeDropParams {
1048
+ receiver: token_receiver_1, amount: token_amount_1,
1049
+ },
1050
+ NativeDropParams {
1051
+ receiver: token_receiver_2, amount: token_amount_2,
1052
+ },
1053
+ ],
1054
+ success: array![true, true],
1055
+ },
1056
+ ),
1057
+ ),
1058
+ ],
1059
+ );
1060
+ }
1061
+
1062
+ #[test]
1063
+ #[fuzzer(runs: 10)]
1064
+ fn native_drop_with_insufficient_balance(
1065
+ endpoint_owner: ContractAddress,
1066
+ eid: Eid,
1067
+ role_admin: RoleAdmin,
1068
+ admin: ContractAddress,
1069
+ price_feed: ContractAddress,
1070
+ token_owner: ContractAddress,
1071
+ origin: Origin,
1072
+ oapp: ContractAddress,
1073
+ token_receiver: ContractAddress,
1074
+ token_amount: u8,
1075
+ sink: ContractAddress,
1076
+ ) {
1077
+ // Make the token amount always non-zero to fail the native token transfer.
1078
+ let token_amount = token_amount.into() + 1;
1079
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1080
+ let ExecutorTest {
1081
+ executor, dispatcher, token, token_dispatcher, ..,
1082
+ } =
1083
+ deploy_executor(
1084
+ endpoint,
1085
+ array![].span(),
1086
+ price_feed,
1087
+ role_admin.address,
1088
+ array![admin].span(),
1089
+ token_owner,
1090
+ );
1091
+
1092
+ // Drain all tokens from the executor.
1093
+ let balance = token_dispatcher.balance_of(executor);
1094
+ cheat_caller_address_once(token, executor);
1095
+ token_dispatcher.transfer(sink, balance);
1096
+ assert(token_dispatcher.balance_of(executor) == 0, 'Non-zero balance for executor');
1097
+
1098
+ let mut spy = spy_events();
1099
+
1100
+ cheat_caller_address_once(executor, admin);
1101
+ dispatcher
1102
+ .native_drop(
1103
+ origin.clone(),
1104
+ oapp,
1105
+ array![NativeDropParams { receiver: token_receiver, amount: token_amount }],
1106
+ );
1107
+
1108
+ spy
1109
+ .assert_emitted(
1110
+ @array![
1111
+ (
1112
+ executor,
1113
+ Executor::Event::NativeDropApplied(
1114
+ NativeDropApplied {
1115
+ origin,
1116
+ dst_eid: eid.eid,
1117
+ oapp,
1118
+ native_drop_params: array![
1119
+ NativeDropParams { receiver: token_receiver, amount: token_amount },
1120
+ ],
1121
+ success: array![false],
1122
+ },
1123
+ ),
1124
+ ),
1125
+ ],
1126
+ );
1127
+ }
1128
+
1129
+ #[test]
1130
+ #[fuzzer(runs: 10)]
1131
+ fn native_drop_with_partial_transfer_success(
1132
+ endpoint_owner: ContractAddress,
1133
+ eid: Eid,
1134
+ role_admin: RoleAdmin,
1135
+ admin: ContractAddress,
1136
+ price_feed: ContractAddress,
1137
+ token_owner: ContractAddress,
1138
+ origin: Origin,
1139
+ oapp: ContractAddress,
1140
+ token_receiver_1: ContractAddress,
1141
+ token_receiver_2: ContractAddress,
1142
+ ) {
1143
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1144
+ let ExecutorTest {
1145
+ executor, dispatcher, token_dispatcher, ..,
1146
+ } =
1147
+ deploy_executor(
1148
+ endpoint,
1149
+ array![].span(),
1150
+ price_feed,
1151
+ role_admin.address,
1152
+ array![admin].span(),
1153
+ token_owner,
1154
+ );
1155
+
1156
+ // We transfer a little more than half of balance of the executor to two native drop receivers.
1157
+ let token_amount = token_dispatcher.balance_of(executor) / 2 + 1;
1158
+ let mut spy = spy_events();
1159
+
1160
+ cheat_caller_address_once(executor, admin);
1161
+ dispatcher
1162
+ .native_drop(
1163
+ origin.clone(),
1164
+ oapp,
1165
+ array![
1166
+ NativeDropParams { receiver: token_receiver_1, amount: token_amount },
1167
+ NativeDropParams { receiver: token_receiver_2, amount: token_amount },
1168
+ ],
1169
+ );
1170
+
1171
+ assert(token_dispatcher.balance_of(token_receiver_1) == token_amount, 'Invalid token amount');
1172
+ assert(token_dispatcher.balance_of(token_receiver_2) == 0, 'Non-zero token amount');
1173
+
1174
+ spy
1175
+ .assert_emitted(
1176
+ @array![
1177
+ (
1178
+ executor,
1179
+ Executor::Event::NativeDropApplied(
1180
+ NativeDropApplied {
1181
+ origin,
1182
+ dst_eid: eid.eid,
1183
+ oapp,
1184
+ native_drop_params: array![
1185
+ NativeDropParams {
1186
+ receiver: token_receiver_1, amount: token_amount,
1187
+ },
1188
+ NativeDropParams {
1189
+ receiver: token_receiver_2, amount: token_amount,
1190
+ },
1191
+ ],
1192
+ success: array![true, false],
1193
+ },
1194
+ ),
1195
+ ),
1196
+ ],
1197
+ );
1198
+ }
1199
+
1200
+ #[test]
1201
+ #[fuzzer(runs: 10)]
1202
+ fn native_drop_when_not_admin(
1203
+ endpoint_owner: ContractAddress,
1204
+ eid: Eid,
1205
+ role_admin: RoleAdmin,
1206
+ price_feed: ContractAddress,
1207
+ token_owner: ContractAddress,
1208
+ origin: Origin,
1209
+ oapp: ContractAddress,
1210
+ user: ContractAddress,
1211
+ ) {
1212
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1213
+ let ExecutorTest {
1214
+ executor, safe_dispatcher, ..,
1215
+ } =
1216
+ deploy_executor(
1217
+ endpoint, array![].span(), price_feed, role_admin.address, array![].span(), token_owner,
1218
+ );
1219
+
1220
+ cheat_caller_address_once(executor, user);
1221
+ let result = safe_dispatcher.native_drop(origin, oapp, array![]);
1222
+
1223
+ assert_panic_with_felt_error(result, MISSING_ROLE);
1224
+ }
1225
+
1226
+ #[test]
1227
+ #[fuzzer(runs: 10)]
1228
+ fn native_drop_and_execute_with_no_native_drop_receiver(
1229
+ endpoint_owner: ContractAddress,
1230
+ eid: Eid,
1231
+ role_admin: RoleAdmin,
1232
+ admin: ContractAddress,
1233
+ price_feed: ContractAddress,
1234
+ token_owner: ContractAddress,
1235
+ oapp: ContractAddress,
1236
+ ) {
1237
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1238
+ let ExecutorTest {
1239
+ executor, dispatcher, ..,
1240
+ } =
1241
+ deploy_executor(
1242
+ endpoint,
1243
+ array![].span(),
1244
+ price_feed,
1245
+ role_admin.address,
1246
+ array![admin].span(),
1247
+ token_owner,
1248
+ );
1249
+ let execute_params = create_mock_execute_params(eid.eid, oapp);
1250
+ let origin = execute_params.origin.clone();
1251
+
1252
+ let mut spy = spy_events();
1253
+
1254
+ cheat_caller_address_once(executor, admin);
1255
+ dispatcher.native_drop_and_execute(array![], execute_params);
1256
+
1257
+ let events = spy.get_events();
1258
+
1259
+ assert!(events.events.len() == 2);
1260
+ assert!(
1261
+ events
1262
+ .is_emitted(
1263
+ executor,
1264
+ @Executor::Event::NativeDropApplied(
1265
+ NativeDropApplied {
1266
+ origin: origin.clone(),
1267
+ dst_eid: eid.eid,
1268
+ oapp,
1269
+ native_drop_params: array![],
1270
+ success: array![],
1271
+ },
1272
+ ),
1273
+ ),
1274
+ );
1275
+ assert!(
1276
+ events
1277
+ .is_emitted(
1278
+ endpoint,
1279
+ @MockEndpoint::Event::PacketDelivered(
1280
+ endpoint_events::PacketDelivered { origin, receiver: oapp },
1281
+ ),
1282
+ ),
1283
+ );
1284
+ }
1285
+
1286
+ #[test]
1287
+ #[fuzzer(runs: 10)]
1288
+ fn native_drop_and_execute_with_single_native_drop_receiver(
1289
+ endpoint_owner: ContractAddress,
1290
+ eid: Eid,
1291
+ role_admin: RoleAdmin,
1292
+ admin: ContractAddress,
1293
+ price_feed: ContractAddress,
1294
+ oapp: ContractAddress,
1295
+ token_owner: ContractAddress,
1296
+ token_receiver: ContractAddress,
1297
+ token_amount: u8,
1298
+ ) {
1299
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1300
+ let ExecutorTest {
1301
+ executor, dispatcher, ..,
1302
+ } =
1303
+ deploy_executor(
1304
+ endpoint,
1305
+ array![].span(),
1306
+ price_feed,
1307
+ role_admin.address,
1308
+ array![admin].span(),
1309
+ token_owner,
1310
+ );
1311
+ let execute_params = create_mock_execute_params(eid.eid, oapp);
1312
+ let origin = execute_params.origin.clone();
1313
+ let native_drop_params = array![
1314
+ NativeDropParams { receiver: token_receiver, amount: token_amount.into() + 1 },
1315
+ ];
1316
+
1317
+ let mut spy = spy_events();
1318
+
1319
+ cheat_caller_address_once(executor, admin);
1320
+ dispatcher.native_drop_and_execute(native_drop_params.clone(), execute_params);
1321
+
1322
+ spy
1323
+ .assert_emitted(
1324
+ @array![
1325
+ (
1326
+ executor,
1327
+ Executor::Event::NativeDropApplied(
1328
+ NativeDropApplied {
1329
+ origin: origin.clone(),
1330
+ dst_eid: eid.eid,
1331
+ oapp,
1332
+ native_drop_params,
1333
+ success: array![true],
1334
+ },
1335
+ ),
1336
+ ),
1337
+ ],
1338
+ );
1339
+ spy
1340
+ .assert_emitted(
1341
+ @array![
1342
+ (
1343
+ endpoint,
1344
+ MockEndpoint::Event::PacketDelivered(
1345
+ endpoint_events::PacketDelivered { origin, receiver: oapp },
1346
+ ),
1347
+ ),
1348
+ ],
1349
+ );
1350
+ }
1351
+
1352
+ #[test]
1353
+ #[fuzzer(runs: 10)]
1354
+ fn native_drop_and_execute_with_insufficient_balance(
1355
+ endpoint_owner: ContractAddress,
1356
+ eid: Eid,
1357
+ role_admin: RoleAdmin,
1358
+ admin: ContractAddress,
1359
+ price_feed: ContractAddress,
1360
+ oapp: ContractAddress,
1361
+ token_owner: ContractAddress,
1362
+ token_receiver: ContractAddress,
1363
+ token_amount: u8,
1364
+ sink: ContractAddress,
1365
+ ) {
1366
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1367
+ let ExecutorTest {
1368
+ executor, dispatcher, token, token_dispatcher, ..,
1369
+ } =
1370
+ deploy_executor(
1371
+ endpoint,
1372
+ array![].span(),
1373
+ price_feed,
1374
+ role_admin.address,
1375
+ array![admin].span(),
1376
+ token_owner,
1377
+ );
1378
+ let execute_params = create_mock_execute_params(eid.eid, oapp);
1379
+ let origin = execute_params.origin.clone();
1380
+ let native_drop_params = array![
1381
+ NativeDropParams { receiver: token_receiver, amount: token_amount.into() + 1 },
1382
+ ];
1383
+
1384
+ // Drain all tokens from the executor.
1385
+ let balance = token_dispatcher.balance_of(executor);
1386
+ cheat_caller_address_once(token, executor);
1387
+ token_dispatcher.transfer(sink, balance);
1388
+ assert(token_dispatcher.balance_of(executor) == 0, 'Non-zero balance for executor');
1389
+
1390
+ let mut spy = spy_events();
1391
+
1392
+ cheat_caller_address_once(executor, admin);
1393
+ dispatcher.native_drop_and_execute(native_drop_params.clone(), execute_params);
1394
+
1395
+ spy
1396
+ .assert_emitted(
1397
+ @array![
1398
+ (
1399
+ executor,
1400
+ Executor::Event::NativeDropApplied(
1401
+ NativeDropApplied {
1402
+ origin: origin.clone(),
1403
+ dst_eid: eid.eid,
1404
+ oapp,
1405
+ native_drop_params,
1406
+ success: array![false],
1407
+ },
1408
+ ),
1409
+ ),
1410
+ ],
1411
+ );
1412
+ // Even when native drops fail, the executor is expected to execute a message and succeed the
1413
+ // whole transaction.
1414
+ spy
1415
+ .assert_emitted(
1416
+ @array![
1417
+ (
1418
+ endpoint,
1419
+ MockEndpoint::Event::PacketDelivered(
1420
+ endpoint_events::PacketDelivered { origin, receiver: oapp },
1421
+ ),
1422
+ ),
1423
+ ],
1424
+ );
1425
+ }
1426
+
1427
+ #[test]
1428
+ #[fuzzer(runs: 10)]
1429
+ fn native_drop_and_execute_when_not_admin(
1430
+ endpoint_owner: ContractAddress,
1431
+ eid: Eid,
1432
+ role_admin: RoleAdmin,
1433
+ price_feed: ContractAddress,
1434
+ token_owner: ContractAddress,
1435
+ receiver: ContractAddress,
1436
+ user: ContractAddress,
1437
+ ) {
1438
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, eid.eid);
1439
+ let ExecutorTest {
1440
+ executor, safe_dispatcher, ..,
1441
+ } =
1442
+ deploy_executor(
1443
+ endpoint, array![].span(), price_feed, role_admin.address, array![].span(), token_owner,
1444
+ );
1445
+ let execute_params = create_mock_execute_params(eid.eid, receiver);
1446
+
1447
+ cheat_caller_address_once(executor, user);
1448
+ let result = safe_dispatcher.native_drop_and_execute(array![], execute_params);
1449
+
1450
+ assert_panic_with_felt_error(result, MISSING_ROLE);
1451
+ }
1452
+
1453
+ //////////////////////////
1454
+ // Implementation tests //
1455
+ //////////////////////////
1456
+
1457
+ #[test]
1458
+ fn impl_layer_zero_worker_interface() {
1459
+ const EID: u32 = 1;
1460
+ let endpoint_owner = 'endpoint owner'.try_into().unwrap();
1461
+
1462
+ let EndpointMock { endpoint, .. } = deploy_mock_endpoint(endpoint_owner, EID);
1463
+ let ExecutorTest {
1464
+ executor, ..,
1465
+ } =
1466
+ deploy_executor(
1467
+ endpoint, array![].span(), ZERO_ADDRESS, ZERO_ADDRESS, array![].span(), endpoint_owner,
1468
+ );
1469
+
1470
+ /// Runtime check that the executor implements the ILayerZeroWorker interface
1471
+ ILayerZeroWorkerDispatcher { contract_address: executor };
1472
+ }