@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,1327 @@
1
+ //! Test endpoint send
2
+
3
+ use layerzero::common::constants::ZERO_ADDRESS;
4
+ use layerzero::common::structs::messaging::MessagingParams;
5
+ use layerzero::endpoint::endpoint::Endpoint;
6
+ use layerzero::endpoint::errors;
7
+ use layerzero::endpoint::events::{DelegateSet, PacketSent};
8
+ use layerzero::endpoint::interfaces::endpoint::{
9
+ IEndpointSafeDispatcher, IEndpointSafeDispatcherTrait,
10
+ };
11
+ use layerzero::endpoint::message_lib_manager::interface::{
12
+ IMessageLibManagerDispatcher, IMessageLibManagerDispatcherTrait,
13
+ };
14
+ use layerzero::message_lib::sml::simple_message_lib::SimpleMessageLib::{
15
+ ISimpleMessageLibHelpersDispatcher, ISimpleMessageLibHelpersDispatcherTrait,
16
+ };
17
+ use layerzero::message_lib::structs::MessageLibType;
18
+ use lz_utils::bytes::ContractAddressIntoBytes32;
19
+ use openzeppelin::access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait};
20
+ use openzeppelin::token::erc20::ERC20Component::Errors::{INSUFFICIENT_BALANCE, TRANSFER_TO_ZERO};
21
+ use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};
22
+ use snforge_std::{
23
+ ContractClassTrait, DeclareResultTrait, EventSpyAssertionsTrait, declare, spy_events,
24
+ start_cheat_caller_address, start_mock_call, stop_cheat_caller_address,
25
+ };
26
+ use starknet::ContractAddress;
27
+ use starkware_utils_testing::test_utils::{assert_panic_with_error, assert_panic_with_felt_error};
28
+ use crate::common::utils::{total_lz_fee_from_receipt, total_native_fee_from_receipt};
29
+ use crate::e2e::utils::deploy_blocked_message_lib;
30
+
31
+
32
+ // Test constants
33
+ const OWNER: ContractAddress = 'owner'.try_into().unwrap();
34
+ const SENDER: ContractAddress = 'sender'.try_into().unwrap();
35
+ const RECEIVER: ContractAddress = 'receiver'.try_into().unwrap();
36
+ const RECEIVER_2: ContractAddress = 'receiver2'.try_into().unwrap();
37
+ const REFUND_ADDRESS: ContractAddress = 'refund'.try_into().unwrap();
38
+ const LIBRARY_ADDRESS: ContractAddress = 'library'.try_into().unwrap();
39
+ const NON_OWNER: ContractAddress = 'non_owner'.try_into().unwrap();
40
+ const LZ_TOKEN: ContractAddress = 'lz_token'.try_into().unwrap();
41
+ const DELEGATE: ContractAddress = 'delegate'.try_into().unwrap();
42
+ const BLOCKED_LIBRARY: ContractAddress = 'blocked_library'.try_into().unwrap();
43
+ const EID: u32 = 1;
44
+ const DST_EID: u32 = 2;
45
+
46
+ // Token amounts
47
+ const INITIAL_SUPPLY: u256 = 1000000_u256; // 1M tokens
48
+ const SENDER_INITIAL_BALANCE: u256 = 10000_u256; // 10K tokens
49
+ const REFUND_INITIAL_BALANCE: u256 = 1000_u256; // 1K tokens
50
+
51
+ // test assert message constants
52
+ const OWNER_NOT_SET: felt252 = 'Owner not set correctly';
53
+ const REGISTER_LIBRARY_FAILED: felt252 = 'registerLibrary failed';
54
+ const SET_SEND_LIBRARY_FAILED: felt252 = 'setSendLibrary failed';
55
+ const SEND_SHOULD_SUCCEED: felt252 = 'Send should succeed';
56
+ const SEND_SHOULD_FAIL: felt252 = 'Send should fail';
57
+ const NONCE_SHOULD_INCREMENT: felt252 = 'Nonce should increment';
58
+ const LZ_RECEIVE_SHOULD_NOT_PANIC: felt252 = 'lzReceive should not panic';
59
+
60
+ fn deploy_mock_erc20() -> (IERC20Dispatcher, ContractAddress) {
61
+ let contract = declare("MockERC20").unwrap().contract_class();
62
+ let constructor_calldata = array![
63
+ INITIAL_SUPPLY.low.into(), INITIAL_SUPPLY.high.into(), OWNER.into(),
64
+ ];
65
+ let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap();
66
+ (IERC20Dispatcher { contract_address }, contract_address)
67
+ }
68
+
69
+ fn deploy_endpoint_with_token(
70
+ token_address: ContractAddress,
71
+ ) -> (IEndpointSafeDispatcher, ContractAddress) {
72
+ let blocked_library = deploy_blocked_message_lib();
73
+ let contract = declare("Endpoint").unwrap().contract_class();
74
+ let constructor_calldata = array![
75
+ OWNER.into(), EID.into(), token_address.into(), blocked_library.into(),
76
+ ];
77
+ let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap();
78
+ (IEndpointSafeDispatcher { contract_address }, contract_address)
79
+ }
80
+
81
+ fn deploy_simple_message_lib(endpoint: ContractAddress) -> ContractAddress {
82
+ let contract = declare("SimpleMessageLib").unwrap().contract_class();
83
+ let (address, _) = contract.deploy(@array![endpoint.into()]).unwrap();
84
+ address
85
+ }
86
+
87
+ fn setup_tokens_and_balances(token: IERC20Dispatcher, endpoint_address: ContractAddress) {
88
+ // Give tokens to SENDER and REFUND_ADDRESS
89
+ start_cheat_caller_address(token.contract_address, OWNER);
90
+ token.transfer(SENDER, SENDER_INITIAL_BALANCE);
91
+ token.transfer(REFUND_ADDRESS, REFUND_INITIAL_BALANCE);
92
+ stop_cheat_caller_address(token.contract_address);
93
+
94
+ // SENDER approves endpoint to spend tokens (large amount for multiple sends)
95
+ start_cheat_caller_address(token.contract_address, SENDER);
96
+ token.approve(endpoint_address, SENDER_INITIAL_BALANCE);
97
+ stop_cheat_caller_address(token.contract_address);
98
+ }
99
+
100
+ fn setup_lz_token_balances(lz_token: IERC20Dispatcher, endpoint_address: ContractAddress) {
101
+ // Give tokens to SENDER
102
+ start_cheat_caller_address(lz_token.contract_address, OWNER);
103
+ lz_token.transfer(SENDER, SENDER_INITIAL_BALANCE);
104
+ stop_cheat_caller_address(lz_token.contract_address);
105
+
106
+ // SENDER approves endpoint to spend tokens (large amount for multiple sends)
107
+ start_cheat_caller_address(lz_token.contract_address, SENDER);
108
+ lz_token.approve(endpoint_address, SENDER_INITIAL_BALANCE);
109
+ stop_cheat_caller_address(lz_token.contract_address);
110
+ }
111
+
112
+ fn reapprove_tokens(token: IERC20Dispatcher, endpoint_address: ContractAddress, amount: u256) {
113
+ start_cheat_caller_address(token.contract_address, OWNER);
114
+ token.transfer(SENDER, amount);
115
+ stop_cheat_caller_address(token.contract_address);
116
+
117
+ // Helper function to re-approve tokens for subsequent sends
118
+ start_cheat_caller_address(token.contract_address, SENDER);
119
+ token.approve(endpoint_address, amount);
120
+ stop_cheat_caller_address(token.contract_address);
121
+ }
122
+
123
+ #[derive(Drop)]
124
+ struct SetupResult {
125
+ endpoint: IEndpointSafeDispatcher,
126
+ endpoint_address: ContractAddress,
127
+ lib_address: ContractAddress,
128
+ token: IERC20Dispatcher,
129
+ lib_helpers: ISimpleMessageLibHelpersDispatcher,
130
+ message_lib_manager: IMessageLibManagerDispatcher,
131
+ }
132
+
133
+ #[feature("safe_dispatcher")]
134
+ fn setup_with_registered_library() -> SetupResult {
135
+ let (token, token_address) = deploy_mock_erc20();
136
+ let (endpoint, endpoint_address) = deploy_endpoint_with_token(token_address);
137
+ let lib_address = deploy_simple_message_lib(endpoint_address);
138
+
139
+ let lib_helpers = ISimpleMessageLibHelpersDispatcher { contract_address: lib_address };
140
+ lib_helpers.set_use_mock_payees();
141
+
142
+ // Setup token balances and approvals
143
+ setup_tokens_and_balances(token, endpoint_address);
144
+
145
+ // Register the library as owner
146
+ start_cheat_caller_address(endpoint_address, OWNER);
147
+ let message_lib_manager = IMessageLibManagerDispatcher { contract_address: endpoint_address };
148
+ // Satisfy registration-time type check
149
+ start_mock_call(lib_address, selector!("message_lib_type"), MessageLibType::SendAndReceive);
150
+ message_lib_manager.register_library(lib_address);
151
+ stop_cheat_caller_address(endpoint_address);
152
+
153
+ SetupResult { endpoint, endpoint_address, lib_address, token, lib_helpers, message_lib_manager }
154
+ }
155
+
156
+ #[feature("safe_dispatcher")]
157
+ fn setup_with_send_library() -> SetupResult {
158
+ let (token, token_address) = deploy_mock_erc20();
159
+ let (endpoint, endpoint_address) = deploy_endpoint_with_token(token_address);
160
+ let lib_address = deploy_simple_message_lib(endpoint_address);
161
+
162
+ let lib_helpers = ISimpleMessageLibHelpersDispatcher { contract_address: lib_address };
163
+ lib_helpers.set_use_mock_payees();
164
+
165
+ // Setup token balances and approvals
166
+ setup_tokens_and_balances(token, endpoint_address);
167
+
168
+ // Register the library as owner
169
+ start_cheat_caller_address(endpoint_address, OWNER);
170
+ let message_lib_manager = IMessageLibManagerDispatcher { contract_address: endpoint_address };
171
+ message_lib_manager.register_library(lib_address);
172
+ stop_cheat_caller_address(endpoint_address);
173
+
174
+ // Set send library for the sender
175
+ start_cheat_caller_address(endpoint_address, SENDER);
176
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
177
+ stop_cheat_caller_address(endpoint_address);
178
+
179
+ SetupResult { endpoint, endpoint_address, lib_address, token, lib_helpers, message_lib_manager }
180
+ }
181
+
182
+ #[derive(Drop)]
183
+ struct SetupResultWithLzToken {
184
+ endpoint: IEndpointSafeDispatcher,
185
+ endpoint_address: ContractAddress,
186
+ lib_address: ContractAddress,
187
+ token: IERC20Dispatcher,
188
+ lib_helpers: ISimpleMessageLibHelpersDispatcher,
189
+ message_lib_manager: IMessageLibManagerDispatcher,
190
+ lz_token_address: ContractAddress,
191
+ lz_token: IERC20Dispatcher,
192
+ }
193
+
194
+ #[derive(Drop)]
195
+ enum PayeeType {
196
+ LzPayees,
197
+ MixedPayees,
198
+ }
199
+
200
+ #[feature("safe_dispatcher")]
201
+ fn setup_with_send_library_and_lz_token(payee_type: PayeeType) -> SetupResultWithLzToken {
202
+ let SetupResult {
203
+ endpoint, endpoint_address, lib_address, token, lib_helpers, message_lib_manager,
204
+ } = setup_with_send_library();
205
+
206
+ // Deploy lz token ERC20
207
+ let (lz_token, lz_token_address) = deploy_mock_erc20();
208
+
209
+ // Set endpoint lz token address
210
+ start_cheat_caller_address(endpoint_address, OWNER);
211
+ endpoint.set_lz_token(lz_token_address).unwrap();
212
+ stop_cheat_caller_address(endpoint_address);
213
+
214
+ // Use mock LZ payees
215
+ match payee_type {
216
+ PayeeType::LzPayees => lib_helpers.set_use_mock_lz_payees(),
217
+ PayeeType::MixedPayees => lib_helpers.set_use_mock_mixed_payees(),
218
+ }
219
+
220
+ setup_lz_token_balances(lz_token, endpoint_address);
221
+
222
+ SetupResultWithLzToken {
223
+ endpoint,
224
+ endpoint_address,
225
+ lib_address,
226
+ token,
227
+ lib_helpers,
228
+ message_lib_manager,
229
+ lz_token_address,
230
+ lz_token,
231
+ }
232
+ }
233
+
234
+ #[test]
235
+ #[feature("safe_dispatcher")]
236
+ fn test_constructor() {
237
+ let (_, token_address) = deploy_mock_erc20();
238
+ let (_endpoint, endpoint_address) = deploy_endpoint_with_token(token_address);
239
+
240
+ // Test ownership
241
+ let ownable = IOwnableDispatcher { contract_address: endpoint_address };
242
+ assert(ownable.owner() == OWNER, OWNER_NOT_SET);
243
+ }
244
+
245
+ #[test]
246
+ #[feature("safe_dispatcher")]
247
+ fn test_send_success() {
248
+ let SetupResult {
249
+ endpoint, endpoint_address, lib_address, token, lib_helpers, message_lib_manager,
250
+ } = setup_with_registered_library();
251
+
252
+ // Set send library for the sender
253
+ start_cheat_caller_address(endpoint_address, SENDER);
254
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
255
+
256
+ let params = MessagingParams {
257
+ dst_eid: DST_EID,
258
+ receiver: RECEIVER.into(),
259
+ message: "test message",
260
+ options: "test options",
261
+ pay_in_lz_token: false,
262
+ };
263
+
264
+ // Check initial balances and allowance
265
+ let sender_balance_before = token.balance_of(SENDER);
266
+ let refund_balance_before = token.balance_of(REFUND_ADDRESS);
267
+ let endpoint_balance_before = token.balance_of(endpoint_address);
268
+ let allowance_before = token.allowance(SENDER, endpoint_address);
269
+
270
+ let mut spy = spy_events();
271
+ let result = endpoint.send(params, REFUND_ADDRESS);
272
+
273
+ // Check that PacketSent event was emitted
274
+ spy
275
+ .assert_emitted(
276
+ @array![
277
+ (
278
+ endpoint_address,
279
+ Endpoint::Event::PacketSent(
280
+ PacketSent {
281
+ encoded_packet: "mock_encoded_packet_data",
282
+ options: "test options",
283
+ send_library: lib_address,
284
+ },
285
+ ),
286
+ ),
287
+ ],
288
+ );
289
+
290
+ stop_cheat_caller_address(endpoint_address);
291
+
292
+ assert(result.is_ok(), SEND_SHOULD_SUCCEED);
293
+ let receipt = result.unwrap();
294
+ assert(receipt.nonce == 1, NONCE_SHOULD_INCREMENT);
295
+ let total_fee = total_native_fee_from_receipt(@receipt);
296
+ assert(total_fee == lib_helpers.get_native_fee(), 'Fee should match mock');
297
+
298
+ // Check balances after send
299
+ let sender_balance_after = token.balance_of(SENDER);
300
+ let refund_balance_after = token.balance_of(REFUND_ADDRESS);
301
+ let endpoint_balance_after = token.balance_of(endpoint_address);
302
+ let allowance_after = token.allowance(SENDER, endpoint_address);
303
+
304
+ // Sender should have spent the fee amount
305
+ assert(
306
+ sender_balance_after == sender_balance_before - allowance_before,
307
+ 'Sender balance should decrease',
308
+ );
309
+
310
+ // Refund address should have received the remainder
311
+ assert(
312
+ refund_balance_after == (refund_balance_before + (allowance_before - total_fee)),
313
+ 'Refund should receive remainder',
314
+ );
315
+
316
+ // Endpoint should not hold any tokens after the transaction
317
+ assert(endpoint_balance_after == endpoint_balance_before, 'Endpoint should not hold tokens');
318
+
319
+ // The allowance should be entirely consumed
320
+ assert(allowance_after == 0, 'Allowance should be consumed');
321
+ assert(allowance_before > 0, 'Should have had allowance');
322
+ assert(
323
+ allowance_before >= sender_balance_before - sender_balance_after, 'Allowance sufficient',
324
+ );
325
+ }
326
+
327
+ ////////////////////////////
328
+ // LZ token payment tests //
329
+ ////////////////////////////
330
+
331
+ #[test]
332
+ #[feature("safe_dispatcher")]
333
+ fn send_lz_token_pay_succeeds() {
334
+ let SetupResultWithLzToken {
335
+ endpoint, endpoint_address, lib_address, lib_helpers, lz_token, ..,
336
+ } = setup_with_send_library_and_lz_token(PayeeType::LzPayees);
337
+
338
+ let params = MessagingParams {
339
+ dst_eid: DST_EID,
340
+ receiver: RECEIVER.into(),
341
+ message: "test message",
342
+ options: "test options",
343
+ pay_in_lz_token: true,
344
+ };
345
+
346
+ // Check initial LZ token balances and allowance
347
+ let sender_balance_before = lz_token.balance_of(SENDER);
348
+ let refund_balance_before = lz_token.balance_of(REFUND_ADDRESS);
349
+ let endpoint_balance_before = lz_token.balance_of(endpoint_address);
350
+ let allowance_before = lz_token.allowance(SENDER, endpoint_address);
351
+
352
+ let mut spy = spy_events();
353
+
354
+ start_cheat_caller_address(endpoint_address, SENDER);
355
+ let result = endpoint.send(params, REFUND_ADDRESS);
356
+
357
+ // Check that PacketSent event was emitted
358
+ spy
359
+ .assert_emitted(
360
+ @array![
361
+ (
362
+ endpoint_address,
363
+ Endpoint::Event::PacketSent(
364
+ PacketSent {
365
+ encoded_packet: "mock_encoded_packet_data",
366
+ options: "test options",
367
+ send_library: lib_address,
368
+ },
369
+ ),
370
+ ),
371
+ ],
372
+ );
373
+
374
+ stop_cheat_caller_address(endpoint_address);
375
+
376
+ let receipt = result.unwrap();
377
+ assert(receipt.nonce == 1, NONCE_SHOULD_INCREMENT);
378
+
379
+ let total_fee = total_lz_fee_from_receipt(@receipt);
380
+ assert(total_fee == lib_helpers.get_lz_token_fee(), 'Fee should match mock');
381
+
382
+ // Check LZ token balances after send
383
+ let sender_balance_after = lz_token.balance_of(SENDER);
384
+ let refund_balance_after = lz_token.balance_of(REFUND_ADDRESS);
385
+ let endpoint_balance_after = lz_token.balance_of(endpoint_address);
386
+ let allowance_after = lz_token.allowance(SENDER, endpoint_address);
387
+
388
+ // Sender should have spent the LZ token fee amount
389
+ assert(
390
+ sender_balance_after == sender_balance_before - allowance_before,
391
+ 'Sender balance should decrease',
392
+ );
393
+
394
+ // Refund address should have received the remainder of the LZ token allowance
395
+ assert(
396
+ refund_balance_after == refund_balance_before + allowance_before - total_fee,
397
+ 'Refund should receive remainder',
398
+ );
399
+
400
+ // Endpoint should not hold any LZ tokens after the transaction
401
+ assert(endpoint_balance_after == endpoint_balance_before, 'Endpoint should not hold tokens');
402
+
403
+ // The LZ token allowance should be entirely consumed
404
+ assert(allowance_after == 0, 'Allowance should be consumed');
405
+ assert(allowance_before > 0, 'Should have had allowance');
406
+ assert(
407
+ allowance_before >= sender_balance_before - sender_balance_after, 'Allowance sufficient',
408
+ );
409
+ }
410
+
411
+ #[test]
412
+ #[feature("safe_dispatcher")]
413
+ fn send_lz_token_mixed_payment_succeeds() {
414
+ let SetupResultWithLzToken {
415
+ endpoint, endpoint_address, token: native_token, lib_address, lib_helpers, lz_token, ..,
416
+ } = setup_with_send_library_and_lz_token(PayeeType::MixedPayees);
417
+
418
+ let params = MessagingParams {
419
+ dst_eid: DST_EID,
420
+ receiver: RECEIVER.into(),
421
+ message: "test message",
422
+ options: "test options",
423
+ pay_in_lz_token: true,
424
+ };
425
+
426
+ // Check initial token balances and allowances
427
+ let sender_lz_before = lz_token.balance_of(SENDER);
428
+ let refund_lz_before = lz_token.balance_of(REFUND_ADDRESS);
429
+ let endpoint_lz_before = lz_token.balance_of(endpoint_address);
430
+ let allowance_lz_before = lz_token.allowance(SENDER, endpoint_address);
431
+
432
+ let sender_native_before = native_token.balance_of(SENDER);
433
+ let refund_native_before = native_token.balance_of(REFUND_ADDRESS);
434
+ let endpoint_native_before = native_token.balance_of(endpoint_address);
435
+ let allowance_native_before = native_token.allowance(SENDER, endpoint_address);
436
+
437
+ let mut spy = spy_events();
438
+
439
+ // SENDER sends a message with mixed payment
440
+ start_cheat_caller_address(endpoint_address, SENDER);
441
+ let result = endpoint.send(params, REFUND_ADDRESS);
442
+
443
+ // Check that PacketSent event was emitted
444
+ spy
445
+ .assert_emitted(
446
+ @array![
447
+ (
448
+ endpoint_address,
449
+ Endpoint::Event::PacketSent(
450
+ PacketSent {
451
+ encoded_packet: "mock_encoded_packet_data",
452
+ options: "test options",
453
+ send_library: lib_address,
454
+ },
455
+ ),
456
+ ),
457
+ ],
458
+ );
459
+
460
+ stop_cheat_caller_address(endpoint_address);
461
+
462
+ let receipt = result.unwrap();
463
+ assert(receipt.nonce == 1, NONCE_SHOULD_INCREMENT);
464
+
465
+ ///////////////////////
466
+ // Native token fees //
467
+ ///////////////////////
468
+
469
+ let total_native_fee = total_native_fee_from_receipt(@receipt);
470
+ assert(total_native_fee == lib_helpers.get_native_fee(), 'Fee should match mock');
471
+
472
+ // Check native token balances after send
473
+ let sender_native_after = native_token.balance_of(SENDER);
474
+ let refund_native_after = native_token.balance_of(REFUND_ADDRESS);
475
+ let endpoint_native_after = native_token.balance_of(endpoint_address);
476
+ let allowance_native_after = native_token.allowance(SENDER, endpoint_address);
477
+
478
+ // Sender should have spent the native fee amount
479
+ assert(
480
+ sender_native_after == sender_native_before - allowance_native_before,
481
+ 'Sender balance should decrease',
482
+ );
483
+
484
+ // Refund address should have received the remainder of the native allowance
485
+ assert(
486
+ refund_native_after == refund_native_before + allowance_native_before - total_native_fee,
487
+ 'Refund should receive remainder',
488
+ );
489
+
490
+ // Endpoint should not hold any native tokens after the transaction
491
+ assert(endpoint_native_after == endpoint_native_before, 'Endpoint should not hold tokens');
492
+
493
+ // The native allowance should be entirely consumed
494
+ assert(allowance_native_after == 0, 'Allowance should be consumed');
495
+ assert(allowance_native_before > 0, 'Should have had allowance');
496
+ assert(
497
+ allowance_native_before >= sender_native_before - sender_native_after,
498
+ 'Allowance sufficient',
499
+ );
500
+
501
+ ///////////////////
502
+ // LZ token fees //
503
+ ///////////////////
504
+
505
+ let total_lz_fee = total_lz_fee_from_receipt(@receipt);
506
+ assert(total_lz_fee == lib_helpers.get_lz_token_fee(), 'Fee should match mock');
507
+
508
+ // Check LZ token balances after send
509
+ let sender_lz_after = lz_token.balance_of(SENDER);
510
+ let refund_lz_after = lz_token.balance_of(REFUND_ADDRESS);
511
+ let endpoint_lz_after = lz_token.balance_of(endpoint_address);
512
+ let allowance_lz_after = lz_token.allowance(SENDER, endpoint_address);
513
+
514
+ // Sender should have spent the LZ token fee amount
515
+ assert(
516
+ sender_lz_after == sender_lz_before - allowance_lz_before, 'Sender balance should decrease',
517
+ );
518
+
519
+ // Refund address should have received the remainder of the LZ token allowance
520
+ assert(
521
+ refund_lz_after == refund_lz_before + allowance_lz_before - total_lz_fee,
522
+ 'Refund should receive remainder',
523
+ );
524
+
525
+ // Endpoint should not hold any LZ tokens after the transaction
526
+ assert(endpoint_lz_after == endpoint_lz_before, 'Endpoint should not hold tokens');
527
+
528
+ // The LZ token allowance should be entirely consumed
529
+ assert(allowance_lz_after == 0, 'Allowance should be consumed');
530
+ assert(allowance_lz_before > 0, 'Should have had allowance');
531
+ assert(allowance_lz_before >= sender_lz_before - sender_lz_after, 'Allowance sufficient');
532
+ }
533
+
534
+ #[test]
535
+ #[feature("safe_dispatcher")]
536
+ fn send_lz_token_fails_when_lz_token_unavailable() {
537
+ let SetupResult { endpoint, endpoint_address, .. } = setup_with_send_library();
538
+
539
+ let params = MessagingParams { pay_in_lz_token: true, ..Default::default() };
540
+
541
+ // Attempt to send with LZ token payment but no LZ token set
542
+ start_cheat_caller_address(endpoint_address, SENDER);
543
+ let res = endpoint.send(params, REFUND_ADDRESS);
544
+ stop_cheat_caller_address(endpoint_address);
545
+
546
+ // Check that we error with LZ token unavailable
547
+ assert_panic_with_error(res, errors::err_lz_token_unavailable());
548
+ }
549
+
550
+ /////////////////
551
+ // Nonce tests //
552
+ /////////////////
553
+
554
+ #[test]
555
+ #[feature("safe_dispatcher")]
556
+ fn test_send_nonce_increments() {
557
+ let SetupResult {
558
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
559
+ } = setup_with_registered_library();
560
+
561
+ // Set send library for the sender
562
+ start_cheat_caller_address(endpoint_address, SENDER);
563
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
564
+
565
+ let params = MessagingParams {
566
+ dst_eid: DST_EID,
567
+ receiver: RECEIVER.into(),
568
+ message: "test message",
569
+ options: "test options",
570
+ pay_in_lz_token: false,
571
+ };
572
+
573
+ // Send multiple messages and verify nonce increments
574
+ let mut i: u64 = 1;
575
+ while i != 5 {
576
+ // Re-approve tokens for each send (endpoint takes entire allowance)
577
+ if i > 1 {
578
+ reapprove_tokens(token, endpoint_address, 2000_u256); // Enough for one send
579
+ }
580
+
581
+ let result = endpoint.send(params.clone(), REFUND_ADDRESS);
582
+ assert(result.is_ok(), SEND_SHOULD_SUCCEED);
583
+ let receipt = result.unwrap();
584
+ assert(receipt.nonce == i, NONCE_SHOULD_INCREMENT);
585
+ i += 1;
586
+ }
587
+
588
+ stop_cheat_caller_address(endpoint_address);
589
+ }
590
+
591
+ #[test]
592
+ #[feature("safe_dispatcher")]
593
+ fn test_send_different_senders_independent_nonces() {
594
+ let SetupResult {
595
+ endpoint, endpoint_address, lib_address, token, ..,
596
+ } = setup_with_registered_library();
597
+
598
+ // Give tokens to NON_OWNER and approve endpoint
599
+ start_cheat_caller_address(token.contract_address, OWNER);
600
+ token.transfer(NON_OWNER, SENDER_INITIAL_BALANCE);
601
+ stop_cheat_caller_address(token.contract_address);
602
+
603
+ start_cheat_caller_address(token.contract_address, NON_OWNER);
604
+ token.approve(endpoint_address, SENDER_INITIAL_BALANCE);
605
+ stop_cheat_caller_address(token.contract_address);
606
+
607
+ let params = MessagingParams {
608
+ dst_eid: DST_EID,
609
+ receiver: RECEIVER.into(),
610
+ message: "test message",
611
+ options: "test options",
612
+ pay_in_lz_token: false,
613
+ };
614
+
615
+ // Set send library for both senders
616
+ start_cheat_caller_address(endpoint_address, SENDER);
617
+ let message_lib_manager_dispatcher = IMessageLibManagerDispatcher {
618
+ contract_address: endpoint_address,
619
+ };
620
+ message_lib_manager_dispatcher.set_send_library(SENDER, DST_EID, lib_address);
621
+ stop_cheat_caller_address(endpoint_address);
622
+
623
+ start_cheat_caller_address(endpoint_address, NON_OWNER);
624
+ message_lib_manager_dispatcher.set_send_library(NON_OWNER, DST_EID, lib_address);
625
+ stop_cheat_caller_address(endpoint_address);
626
+
627
+ // Send from first sender
628
+ start_cheat_caller_address(endpoint_address, SENDER);
629
+ let result1 = endpoint.send(params.clone(), REFUND_ADDRESS).unwrap();
630
+ assert(result1.nonce == 1, 'First sender nonce should be 1');
631
+ stop_cheat_caller_address(endpoint_address);
632
+
633
+ reapprove_tokens(token, endpoint_address, 2000_u256);
634
+
635
+ // Send from second sender
636
+ start_cheat_caller_address(endpoint_address, NON_OWNER);
637
+ let result2 = endpoint.send(params.clone(), REFUND_ADDRESS).unwrap();
638
+ assert(result2.nonce == 1, 'Second sender nonce should be 1');
639
+ stop_cheat_caller_address(endpoint_address);
640
+
641
+ // Re-approve tokens for second send from first sender
642
+ reapprove_tokens(token, endpoint_address, 2000_u256);
643
+
644
+ // Send again from first sender
645
+ start_cheat_caller_address(endpoint_address, SENDER);
646
+ let result3 = endpoint.send(params.clone(), REFUND_ADDRESS).unwrap();
647
+ assert(result3.nonce == 2, 'First sender nonce should be 2');
648
+ stop_cheat_caller_address(endpoint_address);
649
+ }
650
+
651
+ #[test]
652
+ #[feature("safe_dispatcher")]
653
+ fn test_send_different_destinations_independent_nonces() {
654
+ let SetupResult {
655
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
656
+ } = setup_with_registered_library();
657
+
658
+ let dst_eid_1 = 101_u32;
659
+ let dst_eid_2 = 102_u32;
660
+
661
+ // Set send library for both destinations
662
+ start_cheat_caller_address(endpoint_address, SENDER);
663
+ message_lib_manager.set_send_library(SENDER, dst_eid_1, lib_address);
664
+ message_lib_manager.set_send_library(SENDER, dst_eid_2, lib_address);
665
+
666
+ let params1 = MessagingParams {
667
+ dst_eid: dst_eid_1,
668
+ receiver: RECEIVER.into(),
669
+ message: "test message",
670
+ options: "test options",
671
+ pay_in_lz_token: false,
672
+ };
673
+
674
+ let params2 = MessagingParams {
675
+ dst_eid: dst_eid_2,
676
+ receiver: RECEIVER.into(),
677
+ message: "test message",
678
+ options: "test options",
679
+ pay_in_lz_token: false,
680
+ };
681
+
682
+ // Send to first destination
683
+ let result1 = endpoint.send(params1.clone(), REFUND_ADDRESS).unwrap();
684
+ assert(result1.nonce == 1, 'First dest nonce should be 1');
685
+
686
+ reapprove_tokens(token, endpoint_address, 2000_u256);
687
+
688
+ // Send to second destination
689
+ let result2 = endpoint.send(params2.clone(), REFUND_ADDRESS).unwrap();
690
+ assert(result2.nonce == 1, 'Second dest nonce should be 1');
691
+
692
+ // Re-approve tokens for third send
693
+ reapprove_tokens(token, endpoint_address, 2000_u256);
694
+
695
+ // Send again to first destination
696
+ let result3 = endpoint.send(params1.clone(), REFUND_ADDRESS).unwrap();
697
+ assert(result3.nonce == 2, 'First dest nonce should be 2');
698
+
699
+ stop_cheat_caller_address(endpoint_address);
700
+ }
701
+
702
+ #[test]
703
+ #[feature("safe_dispatcher")]
704
+ fn test_send_with_message_lib_failure() {
705
+ let SetupResult {
706
+ endpoint, endpoint_address, lib_address, message_lib_manager, ..,
707
+ } = setup_with_registered_library();
708
+
709
+ // Configure mock library to fail using the correct helper trait
710
+ let lib_helpers = ISimpleMessageLibHelpersDispatcher { contract_address: lib_address };
711
+ lib_helpers.set_should_fail(true);
712
+
713
+ // Set send library for the sender
714
+ start_cheat_caller_address(endpoint_address, SENDER);
715
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
716
+
717
+ let params = MessagingParams {
718
+ dst_eid: DST_EID,
719
+ receiver: RECEIVER.into(),
720
+ message: "test message",
721
+ options: "test options",
722
+ pay_in_lz_token: false,
723
+ };
724
+
725
+ let result = endpoint.send(params, REFUND_ADDRESS);
726
+ stop_cheat_caller_address(endpoint_address);
727
+
728
+ assert(result.is_err(), SEND_SHOULD_FAIL);
729
+ // TODO: how do we fix this? it says error throws with correct error message but test fails
730
+ // assert_panic_with_error(result, "Mock message library failure");
731
+ }
732
+
733
+ #[test]
734
+ #[feature("safe_dispatcher")]
735
+ fn test_send_with_empty_message() {
736
+ let SetupResult {
737
+ endpoint, endpoint_address, lib_address, message_lib_manager, ..,
738
+ } = setup_with_registered_library();
739
+
740
+ start_cheat_caller_address(endpoint_address, SENDER);
741
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
742
+
743
+ let params = MessagingParams {
744
+ dst_eid: DST_EID,
745
+ receiver: RECEIVER.into(),
746
+ message: "",
747
+ options: "test options",
748
+ pay_in_lz_token: false,
749
+ };
750
+
751
+ let result = endpoint.send(params, REFUND_ADDRESS);
752
+ stop_cheat_caller_address(endpoint_address);
753
+
754
+ assert(result.is_ok(), 'empty message should succeed');
755
+ }
756
+
757
+ #[test]
758
+ #[feature("safe_dispatcher")]
759
+ fn test_send_with_empty_options() {
760
+ let SetupResult {
761
+ endpoint, endpoint_address, lib_address, message_lib_manager, ..,
762
+ } = setup_with_registered_library();
763
+
764
+ start_cheat_caller_address(endpoint_address, SENDER);
765
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
766
+
767
+ let params = MessagingParams {
768
+ dst_eid: DST_EID,
769
+ receiver: RECEIVER.into(),
770
+ message: "test message",
771
+ options: "",
772
+ pay_in_lz_token: false,
773
+ };
774
+
775
+ let result = endpoint.send(params, REFUND_ADDRESS);
776
+ stop_cheat_caller_address(endpoint_address);
777
+
778
+ assert(result.is_ok(), 'empty options should succeed');
779
+ }
780
+
781
+ #[test]
782
+ #[feature("safe_dispatcher")]
783
+ fn test_send_payment_flow() {
784
+ let SetupResult {
785
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
786
+ } = setup_with_registered_library();
787
+
788
+ let lib_helpers = ISimpleMessageLibHelpersDispatcher { contract_address: lib_address };
789
+ lib_helpers.set_use_mock_payees();
790
+
791
+ // Set send library for the sender
792
+ start_cheat_caller_address(endpoint_address, SENDER);
793
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
794
+
795
+ let params = MessagingParams {
796
+ dst_eid: DST_EID,
797
+ receiver: RECEIVER.into(),
798
+ message: "test message",
799
+ options: "test options",
800
+ pay_in_lz_token: false,
801
+ };
802
+
803
+ // Record initial balances and allowance
804
+ let sender_balance_before = token.balance_of(SENDER);
805
+ let refund_balance_before = token.balance_of(REFUND_ADDRESS);
806
+ let lib_balance_before = token.balance_of(lib_address);
807
+ let endpoint_balance_before = token.balance_of(endpoint_address);
808
+ let allowance_before = token.allowance(SENDER, endpoint_address);
809
+
810
+ // Get mock payees from SimpleMessageLib
811
+ let mock_payees = lib_helpers.get_mock_payees();
812
+ let payee1_balance_before = token.balance_of(*mock_payees.at(0).receiver);
813
+ let payee2_balance_before = token.balance_of(*mock_payees.at(1).receiver);
814
+
815
+ let result = endpoint.send(params, REFUND_ADDRESS);
816
+ stop_cheat_caller_address(endpoint_address);
817
+
818
+ assert(result.is_ok(), SEND_SHOULD_SUCCEED);
819
+
820
+ // Check that payments were made correctly
821
+ let sender_balance_after = token.balance_of(SENDER);
822
+ let refund_balance_after = token.balance_of(REFUND_ADDRESS);
823
+ let lib_balance_after = token.balance_of(lib_address);
824
+ let endpoint_balance_after = token.balance_of(endpoint_address);
825
+ let allowance_after = token.allowance(SENDER, endpoint_address);
826
+ let payee1_balance_after = token.balance_of(*mock_payees.at(0).receiver);
827
+ let payee2_balance_after = token.balance_of(*mock_payees.at(1).receiver);
828
+
829
+ // The sender should have paid the fee (1000 tokens as per mock)
830
+ let expected_fee = lib_helpers.get_native_fee();
831
+ assert(
832
+ sender_balance_before - sender_balance_after == allowance_before, 'Sender should pay fee',
833
+ );
834
+
835
+ // The refund address should receive the remainder
836
+ assert(
837
+ refund_balance_after == (refund_balance_before + (allowance_before - expected_fee)),
838
+ 'Refund should receive remainder',
839
+ );
840
+
841
+ // The library should not receive tokens (since SimpleMessageLib has empty payees)
842
+ assert(lib_balance_after == lib_balance_before, 'Library shouldnt get tokens');
843
+
844
+ // The endpoint balance should remain unchanged
845
+ assert(endpoint_balance_after == endpoint_balance_before, 'Endpoint balance unchanged');
846
+
847
+ // The mock payees should receive their expected amounts
848
+ let expected_payee1_amount = *mock_payees.at(0).native_amount;
849
+ let expected_payee2_amount = *mock_payees.at(1).native_amount;
850
+ assert(
851
+ payee1_balance_after == payee1_balance_before + expected_payee1_amount,
852
+ 'Payee1 balance increase',
853
+ );
854
+ assert(
855
+ payee2_balance_after == payee2_balance_before + expected_payee2_amount,
856
+ 'Payee2 balance increase',
857
+ );
858
+
859
+ // The allowance should be entirely consumed
860
+ assert(allowance_after == 0, 'Allowance should be consumed');
861
+ assert(allowance_before > 0, 'Should have had allowance');
862
+ assert(
863
+ allowance_before >= sender_balance_before - sender_balance_after, 'Allowance sufficient',
864
+ );
865
+ }
866
+
867
+ #[test]
868
+ #[feature("safe_dispatcher")]
869
+ fn test_send_native_fee_exceeds_allowance() {
870
+ let SetupResult {
871
+ endpoint, endpoint_address, lib_address, token, lib_helpers, message_lib_manager, ..,
872
+ } = setup_with_registered_library();
873
+
874
+ // Set send library for the sender
875
+ start_cheat_caller_address(endpoint_address, SENDER);
876
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
877
+
878
+ let params = MessagingParams {
879
+ dst_eid: DST_EID,
880
+ receiver: RECEIVER.into(),
881
+ message: "test message",
882
+ options: "test options",
883
+ pay_in_lz_token: false,
884
+ };
885
+
886
+ // Set allowance to less than the native fee (1000 tokens)
887
+ // First revoke existing allowance
888
+ start_cheat_caller_address(token.contract_address, SENDER);
889
+ token.approve(endpoint_address, 0);
890
+ // Set insufficient allowance (native fee is 1000, so set to 500)
891
+ token.approve(endpoint_address, lib_helpers.get_native_fee() / 2);
892
+ stop_cheat_caller_address(token.contract_address);
893
+
894
+ let result = endpoint.send(params, REFUND_ADDRESS);
895
+ stop_cheat_caller_address(endpoint_address);
896
+
897
+ assert(result.is_err(), SEND_SHOULD_FAIL);
898
+ assert_panic_with_error(
899
+ result,
900
+ errors::err_insufficient_fee(
901
+ lib_helpers.get_native_fee(), lib_helpers.get_native_fee() / 2, 0, 0,
902
+ ),
903
+ );
904
+ }
905
+
906
+ #[test]
907
+ #[feature("safe_dispatcher")]
908
+ fn test_send_zero_allowance() {
909
+ let SetupResult {
910
+ endpoint, endpoint_address, lib_address, token, lib_helpers, message_lib_manager, ..,
911
+ } = setup_with_registered_library();
912
+
913
+ // Set send library for the sender
914
+ start_cheat_caller_address(endpoint_address, SENDER);
915
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
916
+
917
+ let params = MessagingParams {
918
+ dst_eid: DST_EID,
919
+ receiver: RECEIVER.into(),
920
+ message: "test message",
921
+ options: "test options",
922
+ pay_in_lz_token: false,
923
+ };
924
+
925
+ // Set allowance to zero
926
+ start_cheat_caller_address(token.contract_address, SENDER);
927
+ token.approve(endpoint_address, 0);
928
+ stop_cheat_caller_address(token.contract_address);
929
+
930
+ let result = endpoint.send(params, REFUND_ADDRESS);
931
+ stop_cheat_caller_address(endpoint_address);
932
+
933
+ assert(result.is_err(), SEND_SHOULD_FAIL);
934
+ assert_panic_with_error(
935
+ result, errors::err_insufficient_fee(lib_helpers.get_native_fee(), 0, 0, 0),
936
+ );
937
+ }
938
+
939
+ #[test]
940
+ #[feature("safe_dispatcher")]
941
+ fn test_send_exact_allowance_equals_fee() {
942
+ let SetupResult {
943
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
944
+ } = setup_with_registered_library();
945
+
946
+ // Enable mock payees so we actually have payees to pay
947
+ let lib_helpers = ISimpleMessageLibHelpersDispatcher { contract_address: lib_address };
948
+ lib_helpers.set_use_mock_payees();
949
+
950
+ // Set send library for the sender
951
+ start_cheat_caller_address(endpoint_address, SENDER);
952
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
953
+
954
+ let params = MessagingParams {
955
+ dst_eid: DST_EID,
956
+ receiver: RECEIVER.into(),
957
+ message: "test message",
958
+ options: "test options",
959
+ pay_in_lz_token: false,
960
+ };
961
+
962
+ // Set allowance to exactly match the native fee (1000 tokens)
963
+ start_cheat_caller_address(token.contract_address, SENDER);
964
+ token.approve(endpoint_address, lib_helpers.get_native_fee());
965
+ stop_cheat_caller_address(token.contract_address);
966
+
967
+ let refund_balance_before = token.balance_of(REFUND_ADDRESS);
968
+
969
+ let result = endpoint.send(params, REFUND_ADDRESS);
970
+ stop_cheat_caller_address(endpoint_address);
971
+
972
+ assert(result.is_ok(), SEND_SHOULD_SUCCEED);
973
+
974
+ // Check that refund address receives no tokens (since allowance exactly equals fee)
975
+ let refund_balance_after = token.balance_of(REFUND_ADDRESS);
976
+ assert(refund_balance_after == refund_balance_before, 'No refund for exact allowance');
977
+
978
+ // Check that allowance is fully consumed
979
+ let allowance_after = token.allowance(SENDER, endpoint_address);
980
+ assert(allowance_after == 0, 'Allowance should be consumed');
981
+ }
982
+
983
+ #[test]
984
+ #[feature("safe_dispatcher")]
985
+ fn test_send_with_zero_payees() {
986
+ let SetupResult {
987
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
988
+ } = setup_with_registered_library();
989
+
990
+ // Ensure mock payees are disabled (default behavior)
991
+ let lib_helpers = ISimpleMessageLibHelpersDispatcher { contract_address: lib_address };
992
+ lib_helpers.disable_mock_payees();
993
+
994
+ // Set send library for the sender
995
+ start_cheat_caller_address(endpoint_address, SENDER);
996
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
997
+
998
+ let params = MessagingParams {
999
+ dst_eid: DST_EID,
1000
+ receiver: RECEIVER.into(),
1001
+ message: "test message",
1002
+ options: "test options",
1003
+ pay_in_lz_token: false,
1004
+ };
1005
+
1006
+ let refund_balance_before = token.balance_of(REFUND_ADDRESS);
1007
+ let allowance_before = token.allowance(SENDER, endpoint_address);
1008
+
1009
+ let result = endpoint.send(params, REFUND_ADDRESS);
1010
+ stop_cheat_caller_address(endpoint_address);
1011
+
1012
+ assert(result.is_ok(), SEND_SHOULD_SUCCEED);
1013
+
1014
+ // With no payees, the entire allowance should go to refund address
1015
+ let refund_balance_after = token.balance_of(REFUND_ADDRESS);
1016
+ assert(
1017
+ refund_balance_after == refund_balance_before + allowance_before,
1018
+ 'rem allowance wasnt refunded',
1019
+ );
1020
+ }
1021
+
1022
+ #[test]
1023
+ #[feature("safe_dispatcher")]
1024
+ fn test_send_with_same_sender_and_refund_address() {
1025
+ let SetupResult {
1026
+ endpoint, endpoint_address, lib_address, token, lib_helpers, message_lib_manager, ..,
1027
+ } = setup_with_registered_library();
1028
+
1029
+ // Set send library for the sender
1030
+ start_cheat_caller_address(endpoint_address, SENDER);
1031
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
1032
+
1033
+ let params = MessagingParams {
1034
+ dst_eid: DST_EID,
1035
+ receiver: RECEIVER.into(),
1036
+ message: "test message",
1037
+ options: "test options",
1038
+ pay_in_lz_token: false,
1039
+ };
1040
+
1041
+ let sender_balance_before = token.balance_of(SENDER);
1042
+
1043
+ // Use SENDER as refund address and only approve the fee
1044
+ token.approve(endpoint_address, lib_helpers.get_native_fee());
1045
+ let result = endpoint.send(params, SENDER);
1046
+ stop_cheat_caller_address(endpoint_address);
1047
+
1048
+ assert(result.is_ok(), SEND_SHOULD_SUCCEED);
1049
+
1050
+ // let receipt = result.unwrap();
1051
+
1052
+ // Sender should only lose the fee amount (1000 tokens)
1053
+ let sender_balance_after = token.balance_of(SENDER);
1054
+ assert(
1055
+ sender_balance_after == sender_balance_before - lib_helpers.get_native_fee(),
1056
+ 'Sender should only lose fee',
1057
+ );
1058
+ }
1059
+
1060
+ #[test]
1061
+ #[feature("safe_dispatcher")]
1062
+ fn test_send_with_very_large_message() {
1063
+ let SetupResult {
1064
+ endpoint, endpoint_address, lib_address, message_lib_manager, ..,
1065
+ } = setup_with_registered_library();
1066
+
1067
+ // Set send library for the sender
1068
+ start_cheat_caller_address(endpoint_address, SENDER);
1069
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
1070
+
1071
+ // Create a very large message
1072
+ let mut large_message: ByteArray = Default::default();
1073
+ let mut i = 0;
1074
+ while i != 1000 {
1075
+ large_message
1076
+ .append(
1077
+ @"This is a very long message that will test the system's ability to handle large payloads. ",
1078
+ );
1079
+ i += 1;
1080
+ }
1081
+
1082
+ let params = MessagingParams {
1083
+ dst_eid: DST_EID,
1084
+ receiver: RECEIVER.into(),
1085
+ message: large_message,
1086
+ options: "test options",
1087
+ pay_in_lz_token: false,
1088
+ };
1089
+
1090
+ let result = endpoint.send(params, REFUND_ADDRESS);
1091
+ stop_cheat_caller_address(endpoint_address);
1092
+
1093
+ assert(result.is_ok(), 'Large message should succeed');
1094
+ }
1095
+
1096
+ #[test]
1097
+ #[feature("safe_dispatcher")]
1098
+ fn test_send_with_zero_destination_eid() {
1099
+ let SetupResult {
1100
+ endpoint, endpoint_address, lib_address, message_lib_manager, ..,
1101
+ } = setup_with_registered_library();
1102
+
1103
+ // Set send library for destination EID 0
1104
+ start_cheat_caller_address(endpoint_address, SENDER);
1105
+ message_lib_manager.set_send_library(SENDER, 0, lib_address);
1106
+
1107
+ let params = MessagingParams {
1108
+ dst_eid: 0,
1109
+ receiver: RECEIVER.into(),
1110
+ message: "test message",
1111
+ options: "test options",
1112
+ pay_in_lz_token: false,
1113
+ };
1114
+
1115
+ let result = endpoint.send(params, REFUND_ADDRESS);
1116
+ stop_cheat_caller_address(endpoint_address);
1117
+
1118
+ assert(result.is_ok(), 'Zero dst_eid should succeed');
1119
+ }
1120
+
1121
+ #[test]
1122
+ #[feature("safe_dispatcher")]
1123
+ fn test_send_with_zero_address_receiver() {
1124
+ let SetupResult {
1125
+ endpoint, endpoint_address, lib_address, message_lib_manager, ..,
1126
+ } = setup_with_registered_library();
1127
+
1128
+ // Set send library for the sender
1129
+ start_cheat_caller_address(endpoint_address, SENDER);
1130
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
1131
+
1132
+ let params = MessagingParams {
1133
+ dst_eid: DST_EID,
1134
+ receiver: ZERO_ADDRESS.into(),
1135
+ message: "test message",
1136
+ options: "test options",
1137
+ pay_in_lz_token: false,
1138
+ };
1139
+
1140
+ let result = endpoint.send(params, REFUND_ADDRESS);
1141
+ stop_cheat_caller_address(endpoint_address);
1142
+
1143
+ assert(result.is_ok(), 'Zero receiver should succeed');
1144
+ }
1145
+
1146
+ #[test]
1147
+ #[feature("safe_dispatcher")]
1148
+ fn test_send_with_zero_address_refund() {
1149
+ let SetupResult {
1150
+ endpoint, endpoint_address, lib_address, message_lib_manager, ..,
1151
+ } = setup_with_registered_library();
1152
+
1153
+ // Set send library for the sender
1154
+ start_cheat_caller_address(endpoint_address, SENDER);
1155
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
1156
+
1157
+ let params = MessagingParams {
1158
+ dst_eid: DST_EID,
1159
+ receiver: RECEIVER.into(),
1160
+ message: "test message",
1161
+ options: "test options",
1162
+ pay_in_lz_token: false,
1163
+ };
1164
+
1165
+ // Use zero address as refund address
1166
+ let result = endpoint.send(params, 0.try_into().unwrap());
1167
+ stop_cheat_caller_address(endpoint_address);
1168
+
1169
+ assert_panic_with_felt_error(result, TRANSFER_TO_ZERO);
1170
+ }
1171
+
1172
+ #[test]
1173
+ #[feature("safe_dispatcher")]
1174
+ fn test_send_nonce_overflow_protection() {
1175
+ let SetupResult {
1176
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
1177
+ } = setup_with_registered_library();
1178
+
1179
+ // Set send library for the sender
1180
+ start_cheat_caller_address(endpoint_address, SENDER);
1181
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
1182
+
1183
+ let params = MessagingParams {
1184
+ dst_eid: DST_EID,
1185
+ receiver: RECEIVER.into(),
1186
+ message: "test message",
1187
+ options: "test options",
1188
+ pay_in_lz_token: false,
1189
+ };
1190
+
1191
+ // Send a reasonable number of messages to test nonce increments
1192
+ let mut nonce = 1;
1193
+ while nonce != 10 {
1194
+ if nonce > 1 {
1195
+ reapprove_tokens(token, endpoint_address, 2000_u256);
1196
+ }
1197
+
1198
+ let result = endpoint.send(params.clone(), REFUND_ADDRESS);
1199
+ assert(result.is_ok(), 'Send should succeed');
1200
+ let receipt = result.unwrap();
1201
+ assert(receipt.nonce == nonce, 'Nonce didnt increment correctly');
1202
+ nonce += 1;
1203
+ }
1204
+
1205
+ stop_cheat_caller_address(endpoint_address);
1206
+ }
1207
+
1208
+ #[test]
1209
+ #[feature("safe_dispatcher")]
1210
+ fn test_send_with_insufficient_sender_balance() {
1211
+ let SetupResult {
1212
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
1213
+ } = setup_with_registered_library();
1214
+
1215
+ // Set send library for the sender
1216
+ start_cheat_caller_address(endpoint_address, SENDER);
1217
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
1218
+
1219
+ let params = MessagingParams {
1220
+ dst_eid: DST_EID,
1221
+ receiver: RECEIVER.into(),
1222
+ message: "test message",
1223
+ options: "test options",
1224
+ pay_in_lz_token: false,
1225
+ };
1226
+
1227
+ // Drain sender's balance but keep allowance
1228
+ start_cheat_caller_address(token.contract_address, SENDER);
1229
+ let sender_balance = token.balance_of(SENDER);
1230
+ token.transfer(OWNER, sender_balance);
1231
+ stop_cheat_caller_address(token.contract_address);
1232
+
1233
+ let result = endpoint.send(params, REFUND_ADDRESS);
1234
+ stop_cheat_caller_address(endpoint_address);
1235
+
1236
+ assert_panic_with_felt_error(result, INSUFFICIENT_BALANCE);
1237
+ }
1238
+
1239
+ #[test]
1240
+ #[feature("safe_dispatcher")]
1241
+ fn test_send_consecutive_same_receiver_nonce_tracking() {
1242
+ let SetupResult {
1243
+ endpoint, endpoint_address, lib_address, token, message_lib_manager, ..,
1244
+ } = setup_with_registered_library();
1245
+
1246
+ // Set send library for the sender
1247
+ start_cheat_caller_address(endpoint_address, SENDER);
1248
+ message_lib_manager.set_send_library(SENDER, DST_EID, lib_address);
1249
+
1250
+ // Send to receiver1
1251
+ let params1 = MessagingParams {
1252
+ dst_eid: DST_EID,
1253
+ receiver: RECEIVER.into(),
1254
+ message: "message to receiver1",
1255
+ options: "test options",
1256
+ pay_in_lz_token: false,
1257
+ };
1258
+
1259
+ let result1 = endpoint.send(params1.clone(), REFUND_ADDRESS);
1260
+ assert(result1.is_ok(), 'First send should succeed');
1261
+ assert(result1.unwrap().nonce == 1, 'First nonce should be 1');
1262
+
1263
+ reapprove_tokens(token, endpoint_address, 2000_u256);
1264
+
1265
+ // Send to receiver2
1266
+ let params2 = MessagingParams {
1267
+ dst_eid: DST_EID,
1268
+ receiver: RECEIVER_2.into(),
1269
+ message: "message to receiver2",
1270
+ options: "test options",
1271
+ pay_in_lz_token: false,
1272
+ };
1273
+
1274
+ let result2 = endpoint.send(params2, REFUND_ADDRESS);
1275
+ assert(result2.is_ok(), 'Second send should succeed');
1276
+ assert(result2.unwrap().nonce == 1, 'Second nonce should be 1');
1277
+
1278
+ reapprove_tokens(token, endpoint_address, 2000_u256);
1279
+
1280
+ // Send again to receiver1
1281
+ let result3 = endpoint.send(params1, REFUND_ADDRESS);
1282
+ assert(result3.is_ok(), 'Third send should succeed');
1283
+ assert(result3.unwrap().nonce == 2, 'Third nonce should be 2');
1284
+
1285
+ stop_cheat_caller_address(endpoint_address);
1286
+ }
1287
+
1288
+ ///////////////////
1289
+ // Setters tests //
1290
+ ///////////////////
1291
+
1292
+ #[test]
1293
+ #[feature("safe_dispatcher")]
1294
+ fn test_set_lz_token() {
1295
+ let SetupResult { endpoint, endpoint_address, .. } = setup_with_registered_library();
1296
+ start_cheat_caller_address(endpoint_address, OWNER);
1297
+ let lz_token = endpoint.get_lz_token().unwrap();
1298
+ assert(lz_token == ZERO_ADDRESS, 'lz_token should be 0');
1299
+
1300
+ endpoint.set_lz_token(LZ_TOKEN).unwrap();
1301
+
1302
+ let lz_token = endpoint.get_lz_token().unwrap();
1303
+ assert(lz_token == LZ_TOKEN, 'lz_token should be the same');
1304
+
1305
+ stop_cheat_caller_address(endpoint_address);
1306
+ }
1307
+
1308
+ #[test]
1309
+ #[feature("safe_dispatcher")]
1310
+ fn test_set_delegate() {
1311
+ let (_, token_address) = deploy_mock_erc20();
1312
+ let (endpoint, endpoint_address) = deploy_endpoint_with_token(token_address);
1313
+
1314
+ let mut spy = spy_events();
1315
+
1316
+ start_cheat_caller_address(endpoint_address, SENDER);
1317
+ let _ = endpoint.set_delegate(DELEGATE);
1318
+ stop_cheat_caller_address(endpoint_address);
1319
+
1320
+ let delegate = endpoint.get_delegate(SENDER).unwrap();
1321
+ assert(delegate == DELEGATE, 'delegate should be the same');
1322
+
1323
+ let delegate_event = Endpoint::Event::DelegateSet(
1324
+ DelegateSet { oapp: SENDER, delegate: DELEGATE },
1325
+ );
1326
+ spy.assert_emitted(@array![(endpoint_address, delegate_event)]);
1327
+ }