@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,1038 @@
1
+ //! ULN quote tests
2
+
3
+ use alexandria_bytes::byte_array_ext::ByteArrayTraitExt;
4
+ use layerzero::common::constants::ZERO_ADDRESS;
5
+ use layerzero::common::structs::packet::Packet;
6
+ use layerzero::message_lib::interface::{
7
+ IMessageLibDispatcher, IMessageLibDispatcherTrait, IMessageLibSafeDispatcher,
8
+ IMessageLibSafeDispatcherTrait,
9
+ };
10
+ use layerzero::message_lib::uln::errors::{err_message_too_large, err_must_have_at_least_one_dvn};
11
+ use layerzero::message_lib::uln::events::TreasuryNativeFeeCapSet;
12
+ use layerzero::message_lib::uln::interface::{
13
+ IUltraLightNodeAdminDispatcher, IUltraLightNodeAdminDispatcherTrait,
14
+ IUltraLightNodeAdminSafeDispatcher,
15
+ };
16
+ use layerzero::message_lib::uln::options::TYPE_3;
17
+ use layerzero::message_lib::uln::structs::executor_config::ExecutorConfig;
18
+ use layerzero::message_lib::uln::structs::uln_config::{SetDefaultUlnConfigParam, UlnConfig};
19
+ use layerzero::message_lib::uln::ultra_light_node::UltraLightNode;
20
+ use layerzero::workers::dvn::options::DVN_WORKER_ID;
21
+ use layerzero::workers::executor::options::EXECUTOR_WORKER_ID;
22
+ use lz_utils::bytes::Bytes32;
23
+ use snforge_std::{
24
+ ContractClassTrait, DeclareResultTrait, EventSpyAssertionsTrait, declare, spy_events,
25
+ start_cheat_caller_address, stop_cheat_caller_address,
26
+ };
27
+ use starknet::ContractAddress;
28
+ use starkware_utils_testing::test_utils::assert_panic_with_error;
29
+ use crate::common::test_guid::MAX_U256;
30
+
31
+ // Import shared test utils
32
+ use crate::message_lib::uln::utils::{
33
+ set_oapp_executor_send_config_via_message_lib, set_oapp_uln_send_config_via_message_lib,
34
+ };
35
+ use crate::mocks::treasury::treasury::MockTreasury::{
36
+ IMockTreasuryHelpersDispatcher, IMockTreasuryHelpersDispatcherTrait,
37
+ };
38
+ use crate::mocks::workers::dvn::MockDVN::{
39
+ IMockDVNHelpersDispatcher, IMockDVNHelpersDispatcherTrait,
40
+ };
41
+ use crate::utils::sort_contract_addresses;
42
+
43
+ // Test constants
44
+ pub const OWNER: ContractAddress = 'owner'.try_into().unwrap();
45
+ pub const ENDPOINT: ContractAddress = 'endpoint'.try_into().unwrap();
46
+ pub const SENDER: ContractAddress = 'sender'.try_into().unwrap();
47
+ pub const RECEIVER: ContractAddress = 'receiver'.try_into().unwrap();
48
+ pub const DVN_1: ContractAddress = 'dvn_1'.try_into().unwrap();
49
+ pub const DVN_2: ContractAddress = 'dvn_2'.try_into().unwrap();
50
+ pub const DVN_3: ContractAddress = 'dvn_3'.try_into().unwrap();
51
+ pub const EXECUTOR: ContractAddress = 'executor'.try_into().unwrap();
52
+ pub const PRICE_FEED: ContractAddress = 'price_feed'.try_into().unwrap();
53
+ pub const DST_EID: u32 = 2;
54
+ pub const SRC_EID: u32 = 1;
55
+
56
+ // Quote fee constants
57
+ pub const DVN_QUOTE: u256 = 1000;
58
+ pub const DVN_QUOTE_2: u256 = 1500;
59
+ pub const DVN_QUOTE_OPTIONAL_1: u256 = 800;
60
+ pub const DVN_QUOTE_OPTIONAL_2: u256 = 900;
61
+ pub const DVN_QUOTE_CUSTOM: u256 = 1500;
62
+ pub const EXECUTOR_QUOTE: u256 = 2000;
63
+ pub const EXECUTOR_QUOTE_CUSTOM: u256 = 3000;
64
+ pub const TREASURY_QUOTE: u256 = 50; // Below cap to test normal operation
65
+ pub const TREASURY_QUOTE_AT_CAP: u256 = 200; // At cap
66
+ pub const TREASURY_QUOTE_ABOVE_CAP: u256 = 500; // Above cap to test capping
67
+ pub const ZERO_FEE: u256 = 0;
68
+ pub const LARGE_DVN_FEE: u256 = 1000000000000000000; // 1 ETH
69
+ pub const LARGE_EXECUTOR_FEE: u256 = 500000000000000000; // 0.5 ETH
70
+ pub const LARGE_TREASURY_FEE: u256 = 200000000000000000; // 0.2 ETH
71
+ pub const TREASURY_NATIVE_FEE_CAP: u256 = 200;
72
+
73
+ // Helper functions
74
+ fn deploy_ultra_light_node(
75
+ dvn_quote_amount: u256, executor_quote_amount: u256, treasury_quote_amount: u256,
76
+ ) -> (
77
+ IMessageLibDispatcher,
78
+ IMessageLibSafeDispatcher,
79
+ IUltraLightNodeAdminDispatcher,
80
+ IUltraLightNodeAdminSafeDispatcher,
81
+ ContractAddress,
82
+ ContractAddress,
83
+ ContractAddress,
84
+ ContractAddress,
85
+ ) {
86
+ let contract = declare("UltraLightNode").unwrap().contract_class();
87
+ let treasury = deploy_mock_treasury(treasury_quote_amount);
88
+ let mut constructor_calldata = array![OWNER.into(), treasury.into(), ENDPOINT.into()];
89
+ TREASURY_NATIVE_FEE_CAP.serialize(ref constructor_calldata);
90
+ let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap();
91
+
92
+ let message_lib = IMessageLibDispatcher { contract_address };
93
+ let message_lib_safe = IMessageLibSafeDispatcher { contract_address };
94
+ let admin = IUltraLightNodeAdminDispatcher { contract_address };
95
+ let admin_safe = IUltraLightNodeAdminSafeDispatcher { contract_address };
96
+
97
+ let dvn_address = deploy_mock_dvn(dvn_quote_amount);
98
+ let executor_address = deploy_mock_executor(executor_quote_amount);
99
+
100
+ (
101
+ message_lib,
102
+ message_lib_safe,
103
+ admin,
104
+ admin_safe,
105
+ contract_address,
106
+ treasury,
107
+ dvn_address,
108
+ executor_address,
109
+ )
110
+ }
111
+
112
+ fn deploy_mock_treasury(treasury_fee: u256) -> ContractAddress {
113
+ let contract = declare("MockTreasury").unwrap().contract_class();
114
+ let constructor_calldata = array![treasury_fee.low.into(), treasury_fee.high.into()];
115
+ let (address, _) = contract.deploy(@constructor_calldata).unwrap();
116
+ address
117
+ }
118
+
119
+ fn deploy_mock_dvn(quote_result: u256) -> ContractAddress {
120
+ let contract = declare("MockDVN").unwrap().contract_class();
121
+ let constructor_calldata = array![quote_result.low.into(), quote_result.high.into()];
122
+ let (address, _) = contract.deploy(@constructor_calldata).unwrap();
123
+ address
124
+ }
125
+
126
+ fn deploy_mock_executor(quote_result: u256) -> ContractAddress {
127
+ let contract = declare("MockExecutor").unwrap().contract_class();
128
+ let constructor_calldata = array![
129
+ quote_result.low.into(), quote_result.high.into(), ZERO_ADDRESS.into(), ZERO_ADDRESS.into(),
130
+ ZERO_ADDRESS.into(),
131
+ ];
132
+ let (address, _) = contract.deploy(@constructor_calldata).unwrap();
133
+ address
134
+ }
135
+
136
+ fn create_test_uln_config_with_dvns(
137
+ required_dvns: Array<ContractAddress>,
138
+ optional_dvns: Array<ContractAddress>,
139
+ optional_threshold: u8,
140
+ ) -> UlnConfig {
141
+ UlnConfig {
142
+ confirmations: 10,
143
+ has_confirmations: true,
144
+ required_dvns,
145
+ has_required_dvns: true,
146
+ optional_dvns,
147
+ optional_dvn_threshold: optional_threshold,
148
+ has_optional_dvns: true,
149
+ }
150
+ }
151
+
152
+ fn create_test_executor_config(executor_address: ContractAddress) -> ExecutorConfig {
153
+ ExecutorConfig { max_message_size: 1000, executor: executor_address }
154
+ }
155
+
156
+ fn create_test_packet() -> Packet {
157
+ Packet {
158
+ nonce: 1,
159
+ src_eid: SRC_EID,
160
+ sender: SENDER,
161
+ dst_eid: DST_EID,
162
+ receiver: RECEIVER.into(),
163
+ guid: Bytes32 { value: 'test_guid'.into() },
164
+ message: "test message",
165
+ }
166
+ }
167
+
168
+ fn create_empty_options() -> ByteArray {
169
+ let mut options: ByteArray = Default::default();
170
+ options.append_u16(TYPE_3);
171
+ options
172
+ }
173
+
174
+
175
+ // Helper function to set up default config for an EID (makes EID supported)
176
+ fn setup_default_config_with_dvns(
177
+ admin: IUltraLightNodeAdminDispatcher,
178
+ contract_address: ContractAddress,
179
+ dst_eid: u32,
180
+ required_dvns: Array<ContractAddress>,
181
+ optional_dvns: Array<ContractAddress>,
182
+ optional_threshold: u8,
183
+ executor_address: ContractAddress,
184
+ ) {
185
+ start_cheat_caller_address(contract_address, OWNER);
186
+
187
+ // Set default ULN config
188
+ let default_config = create_test_uln_config_with_dvns(
189
+ required_dvns, optional_dvns, optional_threshold,
190
+ );
191
+ let config_params = array![SetDefaultUlnConfigParam { eid: dst_eid, config: default_config }];
192
+ admin.set_default_uln_send_config(config_params);
193
+
194
+ // Set default executor config
195
+ let executor_config = create_test_executor_config(executor_address);
196
+ admin.set_default_executor_config(dst_eid, executor_config);
197
+
198
+ stop_cheat_caller_address(contract_address);
199
+ }
200
+
201
+
202
+ #[test]
203
+ fn test_quote_with_single_required_dvn() {
204
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
205
+ deploy_ultra_light_node(
206
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
207
+ );
208
+
209
+ // Setup default config with one required DVN
210
+ setup_default_config_with_dvns(
211
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
212
+ );
213
+
214
+ let packet = create_test_packet();
215
+ let options = create_empty_options();
216
+
217
+ let result = message_lib.quote(packet, options, false);
218
+
219
+ // Expected: DVN fee + executor fee + treasury fee
220
+ // Treasury fee = 50, cap = 200, total other fees = 3000, so treasury fee = 50 (not capped)
221
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE; // 1000 + 2000 + 50 = 3050
222
+ assert(result.native_fee == expected_fee, 'incorrect total fee');
223
+ }
224
+
225
+ #[test]
226
+ fn test_quote_with_multiple_required_dvns() {
227
+ let (message_lib, _, admin, _, contract_address, _, dvn1_address, executor_address) =
228
+ deploy_ultra_light_node(
229
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
230
+ );
231
+ let dvn2_address = deploy_mock_dvn(DVN_QUOTE_2);
232
+
233
+ // Setup default config with two required DVNs (need to sort addresses)
234
+ setup_default_config_with_dvns(
235
+ admin,
236
+ contract_address,
237
+ DST_EID,
238
+ sort_contract_addresses(array![dvn1_address, dvn2_address]),
239
+ array![],
240
+ 0,
241
+ executor_address,
242
+ );
243
+
244
+ let packet = create_test_packet();
245
+ let options = create_empty_options();
246
+
247
+ let result = message_lib.quote(packet, options, false);
248
+
249
+ // Expected: DVN1 fee + DVN2 fee + executor fee + treasury fee
250
+ // Treasury fee = 50, cap = 200, total other fees = 4500, so treasury fee = 50 (not capped)
251
+ let expected_fee = DVN_QUOTE
252
+ + DVN_QUOTE_2
253
+ + EXECUTOR_QUOTE
254
+ + TREASURY_QUOTE; // 1000 + 1500 + 2000 + 50 = 4550
255
+ assert(result.native_fee == expected_fee, 'incorrect total fee');
256
+ }
257
+
258
+ #[test]
259
+ fn test_quote_with_optional_dvns() {
260
+ let (message_lib, _, admin, _, contract_address, _, required_dvn, executor_address) =
261
+ deploy_ultra_light_node(
262
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
263
+ );
264
+ let optional_dvn1 = deploy_mock_dvn(DVN_QUOTE_OPTIONAL_1);
265
+ let optional_dvn2 = deploy_mock_dvn(DVN_QUOTE_OPTIONAL_2);
266
+
267
+ // Setup default config with 1 required DVN and 2 optional DVNs with threshold 2
268
+ setup_default_config_with_dvns(
269
+ admin,
270
+ contract_address,
271
+ DST_EID,
272
+ array![required_dvn],
273
+ sort_contract_addresses(array![optional_dvn1, optional_dvn2]),
274
+ 2,
275
+ executor_address,
276
+ );
277
+
278
+ let packet = create_test_packet();
279
+ let options = create_empty_options();
280
+
281
+ let result = message_lib.quote(packet, options, false);
282
+
283
+ // Expected: required DVN + all optional DVNs + executor fee + treasury fee
284
+ let expected_fee = DVN_QUOTE
285
+ + DVN_QUOTE_OPTIONAL_1
286
+ + DVN_QUOTE_OPTIONAL_2
287
+ + EXECUTOR_QUOTE
288
+ + TREASURY_QUOTE;
289
+ assert(result.native_fee == expected_fee, 'incorrect total fee');
290
+ }
291
+
292
+ #[test]
293
+ fn test_quote_with_empty_options() {
294
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
295
+ deploy_ultra_light_node(
296
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
297
+ );
298
+
299
+ // Setup default config
300
+ setup_default_config_with_dvns(
301
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
302
+ );
303
+
304
+ let packet = create_test_packet();
305
+ let options = create_empty_options();
306
+
307
+ let result = message_lib.quote(packet, options, false);
308
+
309
+ // Should work with empty options
310
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
311
+ assert(result.native_fee == expected_fee, 'incorrect fee w/ empty options');
312
+ }
313
+
314
+ #[test]
315
+ fn test_quote_with_type3_options() {
316
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
317
+ deploy_ultra_light_node(
318
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
319
+ );
320
+
321
+ // Setup default config
322
+ setup_default_config_with_dvns(
323
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
324
+ );
325
+
326
+ let packet = create_test_packet();
327
+
328
+ // Create type 3 options with executor and DVN options
329
+ let mut options = Default::default();
330
+ options.append_u16(TYPE_3);
331
+ // Add executor option (worker_id=1, size=5, gas=100000)
332
+ options.append_u8(EXECUTOR_WORKER_ID);
333
+ options.append_u16(5); // option_size
334
+ options.append_u8(1); // option_type (LZ_RECEIVE)
335
+ options.append_u32(100000); // gas
336
+ // Add DVN option (worker_id=2, size=3, idx=0, type=1, data=0x01)
337
+ options.append_u8(DVN_WORKER_ID);
338
+ options.append_u16(3); // option_size
339
+ options.append_u8(0); // dvn_idx
340
+ options.append_u8(1); // option_type
341
+ options.append_u8(0x01); // option_data
342
+
343
+ let result = message_lib.quote(packet, options, false);
344
+
345
+ // Should work with type 3 options
346
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
347
+ assert(result.native_fee == expected_fee, 'incorrect fee w/ type3 options');
348
+ }
349
+
350
+ #[test]
351
+ fn test_quote_with_zero_fees() {
352
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
353
+ deploy_ultra_light_node(
354
+ ZERO_FEE, ZERO_FEE, ZERO_FEE,
355
+ );
356
+
357
+ // Setup default config
358
+ setup_default_config_with_dvns(
359
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
360
+ );
361
+
362
+ let packet = create_test_packet();
363
+ let options = create_empty_options();
364
+
365
+ let result = message_lib.quote(packet, options, false);
366
+
367
+ // Should return zero fee
368
+ let expected_fee = ZERO_FEE + ZERO_FEE + ZERO_FEE;
369
+ assert(result.native_fee == expected_fee, 'fee should be zero');
370
+ }
371
+
372
+ #[test]
373
+ fn test_quote_with_large_fees() {
374
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
375
+ deploy_ultra_light_node(
376
+ LARGE_DVN_FEE, LARGE_EXECUTOR_FEE, LARGE_TREASURY_FEE,
377
+ );
378
+
379
+ // Setup default config
380
+ setup_default_config_with_dvns(
381
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
382
+ );
383
+
384
+ let packet = create_test_packet();
385
+ let options = create_empty_options();
386
+
387
+ let result = message_lib.quote(packet, options, false);
388
+
389
+ // Should handle large fees correctly
390
+ let expected_fee = LARGE_DVN_FEE + LARGE_EXECUTOR_FEE + LARGE_TREASURY_FEE;
391
+ assert(result.native_fee == expected_fee, 'incorrect large fee calculation');
392
+ }
393
+
394
+ #[test]
395
+ fn test_quote_with_different_message_sizes() {
396
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
397
+ deploy_ultra_light_node(
398
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
399
+ );
400
+
401
+ // Setup default config
402
+ setup_default_config_with_dvns(
403
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
404
+ );
405
+
406
+ // Test with different message sizes
407
+ let mut large_packet = create_test_packet();
408
+ large_packet
409
+ .message =
410
+ "This is a much longer message that should affect the calldata_size parameter passed to the executor quote function";
411
+
412
+ let options = create_empty_options();
413
+
414
+ let result = message_lib.quote(large_packet, options, false);
415
+
416
+ // Should work with different message sizes
417
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
418
+ assert(result.native_fee == expected_fee, 'incorrect fee w/ large message');
419
+ }
420
+
421
+ #[test]
422
+ #[feature("safe_dispatcher")]
423
+ fn test_quote_with_unsupported_eid() {
424
+ let (_, message_lib_safe, _, _, _, _, _, _) = deploy_ultra_light_node(
425
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
426
+ );
427
+
428
+ // Don't set up any default config, so EID is unsupported
429
+ let packet = create_test_packet();
430
+ let options = create_empty_options();
431
+
432
+ // Should panic with unsupported EID error when trying to quote
433
+ let result = message_lib_safe.quote(packet.clone(), options, false);
434
+
435
+ // Why does it fail with this error?
436
+ // Because we can't set an OApp config until the default config for that path
437
+ // is set, and if it's not set, when `get_oapp_uln_send_config` tries to call
438
+ // ulnConfig.resolve, it will resolve two "empty" configs together and
439
+ // this is the first assert that it will see at the bottom of .resolve
440
+ assert_panic_with_error(result, err_must_have_at_least_one_dvn());
441
+ }
442
+
443
+ #[test]
444
+ fn test_quote_uses_resolved_config() {
445
+ let (message_lib, _, admin, _, contract_address, _, default_dvn, executor_address) =
446
+ deploy_ultra_light_node(
447
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
448
+ );
449
+ let custom_dvn = deploy_mock_dvn(DVN_QUOTE_CUSTOM);
450
+
451
+ // Setup default config
452
+ setup_default_config_with_dvns(
453
+ admin, contract_address, DST_EID, array![default_dvn], array![], 0, executor_address,
454
+ );
455
+
456
+ // Set custom OApp config
457
+ let custom_config = create_test_uln_config_with_dvns(array![custom_dvn], array![], 0);
458
+
459
+ start_cheat_caller_address(contract_address, ENDPOINT);
460
+ set_oapp_uln_send_config_via_message_lib(contract_address, SENDER, DST_EID, custom_config);
461
+ stop_cheat_caller_address(contract_address);
462
+
463
+ let packet = create_test_packet();
464
+ let options = create_empty_options();
465
+
466
+ let result = message_lib.quote(packet, options, false);
467
+
468
+ // Should use the custom DVN, not the default one
469
+ let expected_fee = DVN_QUOTE_CUSTOM + EXECUTOR_QUOTE + TREASURY_QUOTE;
470
+ assert(result.native_fee == expected_fee, 'should use custom config');
471
+ }
472
+
473
+ #[test]
474
+ fn test_quote_uses_resolved_executor_config() {
475
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, default_executor) =
476
+ deploy_ultra_light_node(
477
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
478
+ );
479
+ let custom_executor = deploy_mock_executor(EXECUTOR_QUOTE_CUSTOM);
480
+
481
+ // Setup default config
482
+ setup_default_config_with_dvns(
483
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, default_executor,
484
+ );
485
+
486
+ // Set custom executor config
487
+ let custom_executor_config = ExecutorConfig {
488
+ max_message_size: 2000, executor: custom_executor,
489
+ };
490
+
491
+ start_cheat_caller_address(contract_address, ENDPOINT);
492
+ set_oapp_executor_send_config_via_message_lib(
493
+ contract_address, SENDER, DST_EID, custom_executor_config,
494
+ );
495
+ stop_cheat_caller_address(contract_address);
496
+
497
+ let packet = create_test_packet();
498
+ let options = create_empty_options();
499
+
500
+ let result = message_lib.quote(packet, options, false);
501
+
502
+ // Should use the custom executor, not the default one
503
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE_CUSTOM + TREASURY_QUOTE;
504
+ assert(result.native_fee == expected_fee, 'should use custom executor');
505
+ }
506
+
507
+ #[test]
508
+ fn test_quote_with_mock_dvn_failure() {
509
+ let (_, _, admin, _, contract_address, _, dvn_address, executor_address) =
510
+ deploy_ultra_light_node(
511
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
512
+ );
513
+
514
+ // Setup default config
515
+ setup_default_config_with_dvns(
516
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
517
+ );
518
+
519
+ // Make DVN fail
520
+ let mut dvn_helpers = IMockDVNHelpersDispatcher { contract_address: dvn_address };
521
+ dvn_helpers.set_should_fail(true);
522
+
523
+ // Test should verify the DVN is configured to fail
524
+ assert(dvn_helpers.get_should_fail(), 'DVN should be set to fail');
525
+ }
526
+
527
+ #[test]
528
+ #[feature("safe_dispatcher")]
529
+ fn test_quote_message_too_large() {
530
+ let (_, message_lib_safe, admin, _, contract_address, _, dvn_address, _) =
531
+ deploy_ultra_light_node(
532
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
533
+ );
534
+
535
+ // Set up executor with a small max_message_size
536
+ let small_max_size = 10_u32;
537
+ let executor_address = deploy_mock_executor(EXECUTOR_QUOTE);
538
+
539
+ // Setup default config with small max message size
540
+ start_cheat_caller_address(contract_address, OWNER);
541
+
542
+ // Set default ULN config
543
+ let default_config = create_test_uln_config_with_dvns(array![dvn_address], array![], 0);
544
+ let config_params = array![SetDefaultUlnConfigParam { eid: DST_EID, config: default_config }];
545
+ admin.set_default_uln_send_config(config_params);
546
+
547
+ // Set default executor config with small max message size
548
+ let executor_config = ExecutorConfig {
549
+ max_message_size: small_max_size, executor: executor_address,
550
+ };
551
+ admin.set_default_executor_config(DST_EID, executor_config);
552
+
553
+ stop_cheat_caller_address(contract_address);
554
+
555
+ // Create packet with message larger than max_message_size
556
+ let mut large_packet = create_test_packet();
557
+ large_packet
558
+ .message =
559
+ "This message is definitely longer than 10 characters and should trigger the message too large error";
560
+
561
+ let options = create_empty_options();
562
+
563
+ // Should panic with message too large error
564
+ let result = message_lib_safe.quote(large_packet.clone(), options, false);
565
+
566
+ // Verify the error matches expected format
567
+ let expected_error = err_message_too_large(large_packet.message.len(), small_max_size.into());
568
+ assert_panic_with_error(result, expected_error);
569
+ }
570
+
571
+ #[test]
572
+ fn test_quote_with_single_dvn_option() {
573
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
574
+ deploy_ultra_light_node(
575
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
576
+ );
577
+
578
+ // Setup default config with one required DVN
579
+ setup_default_config_with_dvns(
580
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
581
+ );
582
+
583
+ let packet = create_test_packet();
584
+
585
+ // Create Type 3 options with DVN option
586
+ let mut options = Default::default();
587
+ options.append_u16(TYPE_3);
588
+ // Add DVN option: worker_id=2, option_size=3, dvn_idx=0, option_type=1, option_data=0x01
589
+ options.append_u8(DVN_WORKER_ID);
590
+ options.append_u16(3); // option_size (dvn_idx + option_type + option_data)
591
+ options.append_u8(0); // dvn_idx (first DVN)
592
+ options.append_u8(1); // option_type (PRECRIME)
593
+ options.append_u8(0x01); // option_data
594
+
595
+ let result = message_lib.quote(packet, options, false);
596
+
597
+ // Expected: DVN fee + executor fee + treasury fee
598
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
599
+ assert(result.native_fee == expected_fee, 'incorrect fee with dvn option');
600
+ }
601
+
602
+ #[test]
603
+ fn test_quote_with_multiple_dvn_options_same_index() {
604
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
605
+ deploy_ultra_light_node(
606
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
607
+ );
608
+
609
+ // Setup default config with one required DVN
610
+ setup_default_config_with_dvns(
611
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
612
+ );
613
+
614
+ let packet = create_test_packet();
615
+
616
+ // Create Type 3 options with multiple DVN options for same DVN index
617
+ let mut options = Default::default();
618
+ options.append_u16(TYPE_3);
619
+ // First DVN option for index 0
620
+ options.append_u8(DVN_WORKER_ID);
621
+ options.append_u16(3); // option_size
622
+ options.append_u8(0); // dvn_idx
623
+ options.append_u8(1); // option_type
624
+ options.append_u8(0x01); // option_data
625
+ // Second DVN option for same index 0
626
+ options.append_u8(DVN_WORKER_ID);
627
+ options.append_u16(4); // option_size
628
+ options.append_u8(0); // dvn_idx
629
+ options.append_u8(1); // option_type
630
+ options.append_u16(0x0203); // option_data (2 bytes)
631
+
632
+ let result = message_lib.quote(packet, options, false);
633
+
634
+ // Should work - options get combined for same DVN index
635
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
636
+ assert(result.native_fee == expected_fee, 'inc fee w/ combined options');
637
+ }
638
+
639
+ #[test]
640
+ fn test_quote_with_multiple_dvns_different_options() {
641
+ let (message_lib, _, admin, _, contract_address, _, dvn1_address, executor_address) =
642
+ deploy_ultra_light_node(
643
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
644
+ );
645
+ let dvn2_address = deploy_mock_dvn(DVN_QUOTE_2);
646
+
647
+ // Setup default config with two required DVNs
648
+ setup_default_config_with_dvns(
649
+ admin,
650
+ contract_address,
651
+ DST_EID,
652
+ sort_contract_addresses(array![dvn1_address, dvn2_address]),
653
+ array![],
654
+ 0,
655
+ executor_address,
656
+ );
657
+
658
+ let packet = create_test_packet();
659
+
660
+ // Create Type 3 options with different DVN options for different DVN indices
661
+ let mut options = Default::default();
662
+ options.append_u16(TYPE_3);
663
+ // DVN option for index 0
664
+ options.append_u8(DVN_WORKER_ID);
665
+ options.append_u16(3); // option_size
666
+ options.append_u8(0); // dvn_idx
667
+ options.append_u8(1); // option_type
668
+ options.append_u8(0x01); // option_data
669
+ // DVN option for index 1
670
+ options.append_u8(DVN_WORKER_ID);
671
+ options.append_u16(4); // option_size
672
+ options.append_u8(1); // dvn_idx
673
+ options.append_u8(1); // option_type
674
+ options.append_u16(0x0203); // option_data (2 bytes)
675
+
676
+ let result = message_lib.quote(packet, options, false);
677
+
678
+ // Expected: DVN1 fee + DVN2 fee + executor fee + treasury fee
679
+ let expected_fee = DVN_QUOTE + DVN_QUOTE_2 + EXECUTOR_QUOTE + TREASURY_QUOTE;
680
+ assert(result.native_fee == expected_fee, 'inc fee w/ multi dvn options');
681
+ }
682
+
683
+ #[test]
684
+ fn test_quote_with_dvn_options_and_executor_options() {
685
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
686
+ deploy_ultra_light_node(
687
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
688
+ );
689
+
690
+ // Setup default config
691
+ setup_default_config_with_dvns(
692
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
693
+ );
694
+
695
+ let packet = create_test_packet();
696
+
697
+ // Create Type 3 options with both executor and DVN options
698
+ let mut options = Default::default();
699
+ options.append_u16(TYPE_3);
700
+ // Executor option
701
+ options.append_u8(EXECUTOR_WORKER_ID);
702
+ options.append_u16(5); // option_size
703
+ options.append_u8(1); // option_type (LZ_RECEIVE)
704
+ options.append_u32(100000); // gas
705
+ // DVN option
706
+ options.append_u8(DVN_WORKER_ID);
707
+ options.append_u16(3); // option_size
708
+ options.append_u8(0); // dvn_idx
709
+ options.append_u8(1); // option_type
710
+ options.append_u8(0x01); // option_data
711
+
712
+ let result = message_lib.quote(packet, options, false);
713
+
714
+ // Should work with both executor and DVN options
715
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
716
+ assert(result.native_fee == expected_fee, 'incorrect fee with both options');
717
+ }
718
+
719
+ #[test]
720
+ fn test_quote_with_optional_dvns_and_options() {
721
+ let (message_lib, _, admin, _, contract_address, _, required_dvn, executor_address) =
722
+ deploy_ultra_light_node(
723
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
724
+ );
725
+ let optional_dvn1 = deploy_mock_dvn(DVN_QUOTE_OPTIONAL_1);
726
+ let optional_dvn2 = deploy_mock_dvn(DVN_QUOTE_OPTIONAL_2);
727
+
728
+ // Setup default config with 1 required DVN and 2 optional DVNs
729
+ setup_default_config_with_dvns(
730
+ admin,
731
+ contract_address,
732
+ DST_EID,
733
+ array![required_dvn],
734
+ sort_contract_addresses(array![optional_dvn1, optional_dvn2]),
735
+ 2,
736
+ executor_address,
737
+ );
738
+
739
+ let packet = create_test_packet();
740
+
741
+ // Create Type 3 options with DVN options for all DVNs
742
+ let mut options = Default::default();
743
+ options.append_u16(TYPE_3);
744
+ // DVN option for index 0 (required DVN)
745
+ options.append_u8(DVN_WORKER_ID);
746
+ options.append_u16(3); // option_size
747
+ options.append_u8(0); // dvn_idx
748
+ options.append_u8(1); // option_type
749
+ options.append_u8(0x01); // option_data
750
+ // DVN option for index 1 (first optional DVN)
751
+ options.append_u8(DVN_WORKER_ID);
752
+ options.append_u16(3); // option_size
753
+ options.append_u8(1); // dvn_idx
754
+ options.append_u8(1); // option_type
755
+ options.append_u8(0x02); // option_data
756
+ // DVN option for index 2 (second optional DVN)
757
+ options.append_u8(DVN_WORKER_ID);
758
+ options.append_u16(3); // option_size
759
+ options.append_u8(2); // dvn_idx
760
+ options.append_u8(1); // option_type
761
+ options.append_u8(0x03); // option_data
762
+
763
+ let result = message_lib.quote(packet, options, false);
764
+
765
+ // Expected: required DVN + all optional DVNs + executor fee + treasury fee
766
+ let expected_fee = DVN_QUOTE
767
+ + DVN_QUOTE_OPTIONAL_1
768
+ + DVN_QUOTE_OPTIONAL_2
769
+ + EXECUTOR_QUOTE
770
+ + TREASURY_QUOTE;
771
+ assert(result.native_fee == expected_fee, 'inc fee w/ optional dvn options');
772
+ }
773
+
774
+ #[test]
775
+ fn test_quote_with_larger_dvn_option_data() {
776
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
777
+ deploy_ultra_light_node(
778
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
779
+ );
780
+
781
+ // Setup default config
782
+ setup_default_config_with_dvns(
783
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
784
+ );
785
+
786
+ let packet = create_test_packet();
787
+
788
+ // Create Type 3 options with larger DVN option data
789
+ let mut options = Default::default();
790
+ options.append_u16(TYPE_3);
791
+ // DVN option with larger data payload
792
+ options.append_u8(DVN_WORKER_ID);
793
+ options.append_u16(10); // option_size (dvn_idx + option_type + 8 bytes data)
794
+ options.append_u8(0); // dvn_idx
795
+ options.append_u8(1); // option_type
796
+ // 8 bytes of option data
797
+ options.append_u64(0x0123456789abcdef); // option_data
798
+
799
+ let result = message_lib.quote(packet, options, false);
800
+
801
+ // Should work with larger option data
802
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
803
+ assert(result.native_fee == expected_fee, 'inc fee w/ large dvn option');
804
+ }
805
+
806
+ #[test]
807
+ fn test_quote_with_dvn_options_missing_index() {
808
+ let (message_lib, _, admin, _, contract_address, _, dvn1_address, executor_address) =
809
+ deploy_ultra_light_node(
810
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
811
+ );
812
+ let dvn2_address = deploy_mock_dvn(DVN_QUOTE_2);
813
+
814
+ // Setup default config with two required DVNs
815
+ setup_default_config_with_dvns(
816
+ admin,
817
+ contract_address,
818
+ DST_EID,
819
+ sort_contract_addresses(array![dvn1_address, dvn2_address]),
820
+ array![],
821
+ 0,
822
+ executor_address,
823
+ );
824
+
825
+ let packet = create_test_packet();
826
+
827
+ // Create Type 3 options with DVN option only for index 0, missing index 1
828
+ let mut options = Default::default();
829
+ options.append_u16(TYPE_3);
830
+ // DVN option for index 0 only
831
+ options.append_u8(DVN_WORKER_ID);
832
+ options.append_u16(3); // option_size
833
+ options.append_u8(0); // dvn_idx
834
+ options.append_u8(1); // option_type
835
+ options.append_u8(0x01); // option_data
836
+
837
+ let result = message_lib.quote(packet, options, false);
838
+
839
+ // Should work - DVN at index 1 gets empty options
840
+ let expected_fee = DVN_QUOTE + DVN_QUOTE_2 + EXECUTOR_QUOTE + TREASURY_QUOTE;
841
+ assert(result.native_fee == expected_fee, 'inc fee w/ missing dvn option');
842
+ }
843
+
844
+ #[test]
845
+ fn test_quote_with_empty_dvn_options_section() {
846
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
847
+ deploy_ultra_light_node(
848
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
849
+ );
850
+
851
+ // Setup default config
852
+ setup_default_config_with_dvns(
853
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
854
+ );
855
+
856
+ let packet = create_test_packet();
857
+
858
+ // Create Type 3 options with only executor options, no DVN options
859
+ let mut options = Default::default();
860
+ options.append_u16(TYPE_3);
861
+ // Only executor option
862
+ options.append_u8(EXECUTOR_WORKER_ID);
863
+ options.append_u16(5); // option_size
864
+ options.append_u8(1); // option_type (LZ_RECEIVE)
865
+ options.append_u32(100000); // gas
866
+
867
+ let result = message_lib.quote(packet, options, false);
868
+
869
+ // Should work - DVN gets empty options
870
+ let expected_fee = DVN_QUOTE + EXECUTOR_QUOTE + TREASURY_QUOTE;
871
+ assert(result.native_fee == expected_fee, 'inc fee w/ no dvn options');
872
+ }
873
+
874
+ #[test]
875
+ fn test_native_cap_with_small_fees() {
876
+ // Use small DVN/executor fees so cap actually applies
877
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
878
+ deploy_ultra_light_node(
879
+ 10, 20, TREASURY_QUOTE_ABOVE_CAP // Small DVN/executor, large treasury
880
+ );
881
+
882
+ setup_default_config_with_dvns(
883
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
884
+ );
885
+
886
+ let packet = create_test_packet();
887
+ let options = create_empty_options();
888
+ let result = message_lib.quote(packet, options, false);
889
+
890
+ // DVN=10, executor=20, total_other_fees=30, cap=200, treasury_quote=500
891
+ // max_native_fee = max(30, 200) = 200
892
+ // actual_treasury_fee = min(500, 200) = 200 (capped!)
893
+ let expected_fee = 10 + 20 + 200; // 230
894
+ assert(result.native_fee == expected_fee, 'treasury fee should be capped');
895
+ }
896
+
897
+ #[test]
898
+ fn test_native_cap_at_threshold() {
899
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
900
+ deploy_ultra_light_node(
901
+ 100, 100, TREASURY_QUOTE_AT_CAP // DVN+executor = 200, treasury = 200
902
+ );
903
+
904
+ setup_default_config_with_dvns(
905
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
906
+ );
907
+
908
+ let packet = create_test_packet();
909
+ let options = create_empty_options();
910
+ let result = message_lib.quote(packet, options, false);
911
+
912
+ // DVN=100, executor=100, total_other_fees=200, cap=200, treasury_quote=200
913
+ // max_native_fee = max(200, 200) = 200
914
+ // actual_treasury_fee = min(200, 200) = 200
915
+ let expected_fee = 100 + 100 + 200; // 400
916
+ assert(result.native_fee == expected_fee, 'treasury fee at cap boundary');
917
+ }
918
+
919
+ #[test]
920
+ fn test_native_cap_with_fees_above_limit() {
921
+ // Use large DVN/executor fees that exceed the cap
922
+ let (message_lib, _, admin, _, contract_address, _, dvn_address, executor_address) =
923
+ deploy_ultra_light_node(
924
+ 150, 150, TREASURY_QUOTE_ABOVE_CAP // DVN+executor = 300, exceeds cap of 200
925
+ );
926
+
927
+ setup_default_config_with_dvns(
928
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
929
+ );
930
+
931
+ let packet = create_test_packet();
932
+ let options = create_empty_options();
933
+ let result = message_lib.quote(packet, options, false);
934
+
935
+ // DVN=150, executor=150, total_other_fees=300, cap=200, treasury_quote=500
936
+ // max_native_fee = max(300, 200) = 300
937
+ // actual_treasury_fee = min(500, 300) = 300
938
+ // OR if cap is absolute: actual_treasury_fee = min(500, 200) = 200
939
+ // Need to test which behavior is implemented
940
+ let expected_fee_if_no_absolute_cap = 150 + 150 + 300; // 600
941
+ let _expected_fee_if_absolute_cap = 150 + 150 + 200; // 500
942
+
943
+ // Based on the cap logic, treasury fee should still be limited by other fees
944
+ // but not necessarily by the absolute cap value
945
+ assert(result.native_fee == expected_fee_if_no_absolute_cap, 'treasury fee follows other');
946
+ }
947
+
948
+ #[test]
949
+ fn test_native_cap_admin_functions() {
950
+ let (_, _, admin, _, contract_address, _, _, _) = deploy_ultra_light_node(
951
+ DVN_QUOTE, EXECUTOR_QUOTE, TREASURY_QUOTE,
952
+ );
953
+
954
+ let mut spy = spy_events();
955
+ start_cheat_caller_address(contract_address, OWNER);
956
+
957
+ // Test getting current cap
958
+ let current_cap = admin.get_treasury_native_fee_cap();
959
+ assert(current_cap == TREASURY_NATIVE_FEE_CAP, 'incorrect initial cap');
960
+
961
+ // Test setting new cap (based on current implementation, can only decrease)
962
+ let new_cap = TREASURY_NATIVE_FEE_CAP - 50; // 200 - 50 = 150
963
+ admin.set_treasury_native_fee_cap(new_cap);
964
+
965
+ let updated_cap = admin.get_treasury_native_fee_cap();
966
+ assert(updated_cap == new_cap, 'cap not updated correctly');
967
+
968
+ stop_cheat_caller_address(contract_address);
969
+ spy
970
+ .assert_emitted(
971
+ @array![
972
+ (
973
+ contract_address,
974
+ UltraLightNode::Event::TreasuryNativeFeeCapSet(
975
+ TreasuryNativeFeeCapSet { native_fee_cap: new_cap },
976
+ ),
977
+ ),
978
+ ],
979
+ );
980
+ }
981
+
982
+ #[test]
983
+ #[fuzzer(runs: 10)]
984
+ fn test_quote_treasury_fee_in_lz_tokens(
985
+ dvn_fee: u64, executor_fee: u64, native_treasury_fee: u64, lz_token_treasury_fee: u64,
986
+ ) {
987
+ let dvn_fee = dvn_fee.into();
988
+ let executor_fee = executor_fee.into();
989
+ let native_treasury_fee = native_treasury_fee.into();
990
+ let lz_token_treasury_fee = lz_token_treasury_fee.into();
991
+
992
+ let (message_lib, _, admin, _, contract_address, treasury, dvn_address, executor_address) =
993
+ deploy_ultra_light_node(
994
+ dvn_fee, executor_fee, native_treasury_fee,
995
+ );
996
+
997
+ setup_default_config_with_dvns(
998
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
999
+ );
1000
+
1001
+ IMockTreasuryHelpersDispatcher { contract_address: treasury }
1002
+ .set_lz_token_fee(Some(lz_token_treasury_fee));
1003
+
1004
+ let packet = create_test_packet();
1005
+ let options = create_empty_options();
1006
+ let result = message_lib.quote(packet, options, true);
1007
+
1008
+ assert(result.native_fee == dvn_fee + executor_fee, 'unexpected native fee');
1009
+ assert(result.lz_token_fee == lz_token_treasury_fee, 'unexpected LZ token fee');
1010
+ }
1011
+
1012
+ #[test]
1013
+ #[fuzzer(runs: 10)]
1014
+ fn test_quote_uncapped_treasury_fee_in_lz_tokens(
1015
+ dvn_fee: u64, executor_fee: u64, native_treasury_fee: u64,
1016
+ ) {
1017
+ let dvn_fee = dvn_fee.into();
1018
+ let executor_fee = executor_fee.into();
1019
+ let native_treasury_fee = native_treasury_fee.into();
1020
+
1021
+ let (message_lib, _, admin, _, contract_address, treasury, dvn_address, executor_address) =
1022
+ deploy_ultra_light_node(
1023
+ dvn_fee, executor_fee, native_treasury_fee,
1024
+ );
1025
+
1026
+ setup_default_config_with_dvns(
1027
+ admin, contract_address, DST_EID, array![dvn_address], array![], 0, executor_address,
1028
+ );
1029
+
1030
+ IMockTreasuryHelpersDispatcher { contract_address: treasury }.set_lz_token_fee(Some(MAX_U256));
1031
+
1032
+ let packet = create_test_packet();
1033
+ let options = create_empty_options();
1034
+ let result = message_lib.quote(packet, options, true);
1035
+
1036
+ assert(result.native_fee == dvn_fee + executor_fee, 'unexpected native fee');
1037
+ assert(result.lz_token_fee == MAX_U256, 'unexpected LZ token fee');
1038
+ }