@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,879 @@
1
+ //! Price feed tests
2
+
3
+ use layerzero::common::constants::MAX_V1_EID;
4
+ use layerzero::workers::price_feed::constants::PRICE_RATIO_DENOMINATOR;
5
+ use layerzero::workers::price_feed::errors::err_lz_price_feed_only_price_updater;
6
+ use layerzero::workers::price_feed::events::FeeWithdrawn;
7
+ use layerzero::workers::price_feed::interface::{
8
+ ILayerZeroPriceFeedDispatcher, ILayerZeroPriceFeedDispatcherTrait, IPriceFeedDispatcherTrait,
9
+ IPriceFeedSafeDispatcherTrait,
10
+ };
11
+ use layerzero::workers::price_feed::price_feed::PriceFeed::{
12
+ ETHEREUM_MAINNET_EID, Event as PriceFeedEvent,
13
+ };
14
+ use layerzero::workers::price_feed::structs::{
15
+ ArbitrumPriceExt, GetFeeResponse, ModelType, Price, SetEidToModelTypeParam, SetPriceParam,
16
+ UpdatePriceExt,
17
+ };
18
+ use openzeppelin::access::ownable::OwnableComponent;
19
+ use openzeppelin::token::erc20::ERC20Component::{
20
+ Errors as ERC20Errors, Event as ERC20Event, Transfer,
21
+ };
22
+ use openzeppelin::token::erc20::interface::IERC20DispatcherTrait;
23
+ use snforge_std::fuzzable::{FuzzableU256, FuzzableU32};
24
+ use snforge_std::{
25
+ DeclareResultTrait, EventSpyAssertionsTrait, declare, get_class_hash, spy_events,
26
+ start_cheat_caller_address, stop_cheat_caller_address,
27
+ };
28
+ use starknet::ContractAddress;
29
+ use starkware_utils_testing::test_utils::{assert_panic_with_error, assert_panic_with_felt_error};
30
+ use crate::fuzzable::contract_address::FuzzableContractAddress;
31
+ use crate::fuzzable::eid::{Eid, FuzzableEid};
32
+ use crate::fuzzable::model_type::FuzzableModelType;
33
+ use crate::fuzzable::price::{FuzzableArbitrumPriceExt, FuzzablePrice};
34
+ use crate::workers::base::utils::{ERC20Mock, deploy_mock_erc20};
35
+ use crate::workers::price_feed::utils::{PriceFeedDeploy, TEN_GWEI, deploy_price_feed};
36
+
37
+ const OWNER: ContractAddress = 'owner'.try_into().unwrap();
38
+ const PRICE_UPDATER: ContractAddress = 'price_updater'.try_into().unwrap();
39
+ const ENDPOINT: ContractAddress = 'endpoint'.try_into().unwrap();
40
+ const NATIVE_PRICE_USD: u128 = 1234567890;
41
+ const ARBITRUM_COMPRESSION_PERCENT: u32 = 100;
42
+
43
+ #[test]
44
+ #[fuzzer(runs: 10)]
45
+ fn should_set_eid_to_model_type(
46
+ owner: ContractAddress, price_updater: ContractAddress, eid_1: Eid, eid_2: Eid, eid_3: Eid,
47
+ ) {
48
+ let eid_1 = eid_1.eid;
49
+ let eid_2 = eid_2.eid;
50
+ let eid_3 = eid_3.eid;
51
+
52
+ // Ensure that eid_1, eid_2, and eid_3 are all different
53
+ if eid_1 == eid_2 || eid_1 == eid_3 || eid_2 == eid_3 {
54
+ return;
55
+ }
56
+
57
+ let params = array![
58
+ SetEidToModelTypeParam { eid: eid_1, model_type: ModelType::ARB_STACK },
59
+ SetEidToModelTypeParam { eid: eid_2, model_type: ModelType::OP_STACK },
60
+ SetEidToModelTypeParam { eid: eid_3, model_type: ModelType::DEFAULT },
61
+ ];
62
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(owner, price_updater);
63
+
64
+ // Caller is the owner
65
+ start_cheat_caller_address(price_feed, owner);
66
+ dispatcher.set_eid_to_model_type(params);
67
+ stop_cheat_caller_address(price_feed);
68
+
69
+ // Check that the model type is set correctly
70
+ assert_eq!(dispatcher.get_eid_to_model_type(eid_1), ModelType::ARB_STACK);
71
+ assert_eq!(dispatcher.get_eid_to_model_type(eid_2), ModelType::OP_STACK);
72
+ assert_eq!(dispatcher.get_eid_to_model_type(eid_3), ModelType::DEFAULT);
73
+ }
74
+
75
+ #[test]
76
+ #[fuzzer(runs: 10)]
77
+ #[feature("safe_dispatcher")]
78
+ fn should_fail_to_set_eid_to_model_type_when_not_owner(
79
+ owner: ContractAddress,
80
+ not_owner: ContractAddress,
81
+ price_updater: ContractAddress,
82
+ eid: Eid,
83
+ model_type: ModelType,
84
+ ) {
85
+ // Ensure that not_owner is not the owner
86
+ // We are testing the case where the caller is not the owner
87
+ if owner == not_owner {
88
+ return;
89
+ }
90
+
91
+ let eid = eid.eid;
92
+ let params = array![SetEidToModelTypeParam { eid, model_type }];
93
+ let PriceFeedDeploy {
94
+ price_feed, safe_dispatcher, ..,
95
+ } = deploy_price_feed(owner, price_updater);
96
+
97
+ // Caller is not the owner
98
+ start_cheat_caller_address(price_feed, not_owner);
99
+ let res = safe_dispatcher.set_eid_to_model_type(params);
100
+ stop_cheat_caller_address(price_feed);
101
+
102
+ // Check that the model type is not set
103
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
104
+ }
105
+
106
+ #[test]
107
+ #[fuzzer(runs: 10)]
108
+ fn should_set_price(
109
+ owner: ContractAddress, price_updater: ContractAddress, eid: Eid, price: Price,
110
+ ) {
111
+ let eid = eid.eid;
112
+ let params = array![SetPriceParam { eid, price: price.clone() }];
113
+ let PriceFeedDeploy {
114
+ price_feed, dispatcher, layer_zero, ..,
115
+ } = deploy_price_feed(owner, price_updater);
116
+
117
+ // Caller is the owner
118
+ start_cheat_caller_address(price_feed, owner);
119
+ dispatcher.set_price(params);
120
+ stop_cheat_caller_address(price_feed);
121
+
122
+ // Check that the price is set correctly
123
+ assert_eq!(layer_zero.get_price(eid), price);
124
+ }
125
+
126
+ #[test]
127
+ #[fuzzer(runs: 10)]
128
+ fn should_set_price_by_price_updater(
129
+ owner: ContractAddress, price_updater: ContractAddress, eid: Eid, price: Price,
130
+ ) {
131
+ let eid = eid.eid;
132
+ let params = array![SetPriceParam { eid, price }];
133
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(owner, price_updater);
134
+
135
+ // Caller is the price updater
136
+ start_cheat_caller_address(price_feed, price_updater);
137
+ dispatcher.set_price(params);
138
+ stop_cheat_caller_address(price_feed);
139
+
140
+ // Check that the price updater is set correctly
141
+ assert!(dispatcher.get_price_updater(price_updater));
142
+ }
143
+
144
+ #[test]
145
+ #[fuzzer(runs: 10)]
146
+ #[feature("safe_dispatcher")]
147
+ fn should_fail_to_set_price_when_not_owner_or_price_updater(
148
+ owner: ContractAddress,
149
+ not_owner_or_price_updater: ContractAddress,
150
+ price_updater: ContractAddress,
151
+ eid: Eid,
152
+ price: Price,
153
+ ) {
154
+ // Ensure that not_owner_or_price_updater is not the owner or the price updater
155
+ // We are testing the case where the caller is not the owner or the price updater
156
+ if owner == not_owner_or_price_updater || price_updater == not_owner_or_price_updater {
157
+ return;
158
+ }
159
+
160
+ let eid = eid.eid;
161
+ let params = array![SetPriceParam { eid, price }];
162
+ let PriceFeedDeploy {
163
+ price_feed, safe_dispatcher, ..,
164
+ } = deploy_price_feed(owner, price_updater);
165
+
166
+ // Caller is not the owner or the price updater
167
+ start_cheat_caller_address(price_feed, not_owner_or_price_updater);
168
+ let res = safe_dispatcher.set_price(params);
169
+ stop_cheat_caller_address(price_feed);
170
+
171
+ // Check that set_price panics with the expected error
172
+ assert_panic_with_error(res, err_lz_price_feed_only_price_updater());
173
+ }
174
+
175
+ #[test]
176
+ #[fuzzer(runs: 10)]
177
+ fn should_estimate_fee_with_default_model(
178
+ owner: ContractAddress, price_updater: ContractAddress, eid: Eid, price: Price,
179
+ ) {
180
+ let eid = eid.eid;
181
+ let calldata_size: u32 = 100;
182
+ let gas: u256 = 50000;
183
+
184
+ let price = Price {
185
+ gas_price_in_unit: TEN_GWEI, gas_per_byte: 16, price_ratio: 2 * PRICE_RATIO_DENOMINATOR,
186
+ };
187
+ let params = array![SetPriceParam { eid: eid % MAX_V1_EID, price: price.clone() }];
188
+ let PriceFeedDeploy {
189
+ price_feed, dispatcher, layer_zero, ..,
190
+ } = deploy_price_feed(owner, price_updater);
191
+
192
+ // Caller is the owner
193
+ start_cheat_caller_address(price_feed, owner);
194
+ dispatcher.set_price(params);
195
+ stop_cheat_caller_address(price_feed);
196
+
197
+ let estimate = layer_zero.estimate_fee_on_send(eid, calldata_size, gas);
198
+
199
+ // gas_for_call_data = calldata_size * gas_per_byte = 100 * 16 = 1600
200
+ // remote_fee = (gas_for_call_data + gas) * gas_price_in_unit
201
+ // remote_fee = (1600 + 50000) * 10_000_000_000 = 516_000_000_000_000
202
+ // expected_gas_fee = remote_fee * price_ratio / PRICE_RATIO_DENOMINATOR
203
+ // expected_gas_fee = 516_000_000_000_000 * 200000000000000000000 / 100000000000000000000 =
204
+ let expected_estimate = GetFeeResponse {
205
+ gas_fee: 1_032_000_000_000_000,
206
+ price_ratio: price.price_ratio,
207
+ price_ratio_denominator: PRICE_RATIO_DENOMINATOR,
208
+ native_price_usd: 0,
209
+ };
210
+
211
+ // Check that the fee estimate is correct
212
+ assert_eq!(estimate, expected_estimate);
213
+ }
214
+
215
+ #[test]
216
+ #[fuzzer(runs: 10)]
217
+ fn should_return_zero_for_get_fee(
218
+ owner: ContractAddress,
219
+ price_updater: ContractAddress,
220
+ eid: Eid,
221
+ calldata_size: u256,
222
+ gas: u256,
223
+ ) {
224
+ let eid = eid.eid;
225
+ let PriceFeedDeploy { layer_zero, .. } = deploy_price_feed(owner, price_updater);
226
+
227
+ // Check that get_fee returns 0
228
+ assert(layer_zero.get_fee(eid, calldata_size, gas) == 0, 'fee should be 0');
229
+ }
230
+
231
+ ///////////////////
232
+ // Upgrade tests //
233
+ ///////////////////
234
+
235
+ #[test]
236
+ #[fuzzer(runs: 10)]
237
+ fn upgrade_succeeds(owner: ContractAddress, price_updater: ContractAddress) {
238
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(owner, price_updater);
239
+ let new_class_hash = declare("MockBaseWorker").unwrap().contract_class().class_hash;
240
+
241
+ // Caller is the owner
242
+ start_cheat_caller_address(price_feed, owner);
243
+ dispatcher.upgrade(*new_class_hash);
244
+ stop_cheat_caller_address(price_feed);
245
+
246
+ // Check that the contract is upgraded
247
+ assert(get_class_hash(price_feed) == *new_class_hash, 'upgrade should succeed');
248
+ }
249
+
250
+ #[test]
251
+ #[fuzzer(runs: 10)]
252
+ #[feature("safe_dispatcher")]
253
+ fn upgrade_fails_when_not_owner(
254
+ owner: ContractAddress, not_owner: ContractAddress, price_updater: ContractAddress,
255
+ ) {
256
+ // Ensure that not_owner is not the owner
257
+ // We are testing the case where the caller is not the owner
258
+ if owner == not_owner {
259
+ return;
260
+ }
261
+
262
+ let PriceFeedDeploy {
263
+ price_feed, safe_dispatcher, ..,
264
+ } = deploy_price_feed(owner, price_updater);
265
+ let new_class_hash = declare("MockBaseWorker").unwrap().contract_class().class_hash;
266
+
267
+ // Caller is not the owner
268
+ start_cheat_caller_address(price_feed, not_owner);
269
+ let res = safe_dispatcher.upgrade(*new_class_hash);
270
+ stop_cheat_caller_address(price_feed);
271
+
272
+ // Check that upgrade panics with the expected error
273
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
274
+ }
275
+
276
+ #[test]
277
+ #[fuzzer(runs: 10)]
278
+ fn upgrade_and_call_succeeds(owner: ContractAddress, price_updater: ContractAddress) {
279
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(owner, price_updater);
280
+ let new_class_hash = declare("PriceFeed").unwrap().contract_class().class_hash;
281
+
282
+ // Call data
283
+ let endpoint: ContractAddress = 'endpoint'.try_into().unwrap();
284
+ let call_data = array![endpoint.into()];
285
+
286
+ // Upgrade and call
287
+ // Caller is the owner
288
+ start_cheat_caller_address(price_feed, owner);
289
+ dispatcher.upgrade_and_call(*new_class_hash, selector!("set_endpoint"), call_data.span());
290
+ stop_cheat_caller_address(price_feed);
291
+
292
+ // Check that the function was called correctly
293
+ assert(dispatcher.get_endpoint() == endpoint, 'endpoint should be set');
294
+
295
+ // Check that the contract is upgraded
296
+ assert(get_class_hash(price_feed) == *new_class_hash, 'upgrade should succeed');
297
+ }
298
+
299
+ #[test]
300
+ #[fuzzer(runs: 10)]
301
+ #[feature("safe_dispatcher")]
302
+ fn upgrade_and_call_fails_when_not_owner(
303
+ owner: ContractAddress, not_owner: ContractAddress, price_updater: ContractAddress,
304
+ ) {
305
+ // Ensure that not_owner is not the owner
306
+ // We are testing the case where the caller is not the owner
307
+ if owner == not_owner {
308
+ return;
309
+ }
310
+
311
+ let PriceFeedDeploy {
312
+ price_feed, safe_dispatcher, ..,
313
+ } = deploy_price_feed(owner, price_updater);
314
+ let new_class_hash = declare("PriceFeed").unwrap().contract_class().class_hash;
315
+
316
+ // Caller is not the owner
317
+ start_cheat_caller_address(price_feed, not_owner);
318
+ let res = safe_dispatcher.upgrade_and_call(*new_class_hash, 0, array![].span());
319
+ stop_cheat_caller_address(price_feed);
320
+
321
+ // Check that upgrade panics with the expected error
322
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
323
+ }
324
+
325
+ /////////////////////////
326
+ // Price updater tests //
327
+ /////////////////////////
328
+
329
+ #[test]
330
+ #[fuzzer(runs: 10)]
331
+ fn should_set_price_updater(
332
+ owner: ContractAddress,
333
+ price_updater: ContractAddress,
334
+ new_price_updater: ContractAddress,
335
+ eid: Eid,
336
+ price: Price,
337
+ ) {
338
+ let PriceFeedDeploy {
339
+ price_feed, dispatcher, layer_zero, ..,
340
+ } = deploy_price_feed(owner, price_updater);
341
+
342
+ // Set new price updater via owner
343
+ start_cheat_caller_address(price_feed, owner);
344
+ dispatcher.set_price_updater(new_price_updater, true);
345
+ stop_cheat_caller_address(price_feed);
346
+
347
+ // Check that the new price updater is set
348
+ assert!(dispatcher.get_price_updater(new_price_updater));
349
+
350
+ let eid = eid.eid;
351
+ let params = array![SetPriceParam { eid, price: price.clone() }];
352
+
353
+ // Set the price via the new price updater
354
+ start_cheat_caller_address(price_feed, new_price_updater);
355
+ dispatcher.set_price(params);
356
+ stop_cheat_caller_address(price_feed);
357
+
358
+ // Check that the price is set correctly
359
+ assert_eq!(layer_zero.get_price(eid), price);
360
+ }
361
+
362
+ #[test]
363
+ #[fuzzer(runs: 10)]
364
+ #[feature("safe_dispatcher")]
365
+ fn should_fail_to_set_price_updater_when_not_owner(
366
+ owner: ContractAddress,
367
+ not_owner: ContractAddress,
368
+ price_updater: ContractAddress,
369
+ new_price_updater: ContractAddress,
370
+ ) {
371
+ // Ensure that not_owner is not the owner
372
+ // We are testing the case where the caller is not the owner
373
+ if owner == not_owner {
374
+ return;
375
+ }
376
+
377
+ let PriceFeedDeploy {
378
+ price_feed, safe_dispatcher, ..,
379
+ } = deploy_price_feed(owner, price_updater);
380
+
381
+ // Caller is not the owner
382
+ start_cheat_caller_address(price_feed, not_owner);
383
+ let res = safe_dispatcher.set_price_updater(new_price_updater, true);
384
+ stop_cheat_caller_address(price_feed);
385
+
386
+ // Check that set_price_updater panics with the expected error
387
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
388
+ }
389
+
390
+ #[test]
391
+ #[fuzzer(runs: 10)]
392
+ fn should_estimate_fee_with_optimism_model(owner: ContractAddress, price_updater: ContractAddress) {
393
+ let PriceFeedDeploy {
394
+ price_feed, dispatcher, layer_zero, ..,
395
+ } = deploy_price_feed(owner, price_updater);
396
+
397
+ let eid = 1;
398
+ let calldata_size = 100;
399
+ let gas = 50000;
400
+
401
+ let l2_price = Price {
402
+ gas_price_in_unit: TEN_GWEI, gas_per_byte: 16, price_ratio: PRICE_RATIO_DENOMINATOR,
403
+ };
404
+ let l1_price = Price {
405
+ gas_price_in_unit: 2 * TEN_GWEI, gas_per_byte: 0, price_ratio: PRICE_RATIO_DENOMINATOR,
406
+ };
407
+
408
+ let model_params = array![SetEidToModelTypeParam { eid, model_type: ModelType::OP_STACK }];
409
+ let prices_params = array![
410
+ SetPriceParam { eid, price: l2_price.clone() },
411
+ SetPriceParam { eid: ETHEREUM_MAINNET_EID, price: l1_price.clone() },
412
+ ];
413
+
414
+ // Caller is the owner, set model type and prices
415
+ start_cheat_caller_address(price_feed, owner);
416
+ dispatcher.set_eid_to_model_type(model_params);
417
+ dispatcher.set_price(prices_params);
418
+ stop_cheat_caller_address(price_feed);
419
+
420
+ // Check that the model type is set correctly
421
+ assert_eq!(dispatcher.get_eid_to_model_type(eid), ModelType::OP_STACK);
422
+
423
+ // Estimate fee
424
+ let estimate = layer_zero.estimate_fee_on_send(eid, calldata_size, gas);
425
+
426
+ // L2 fee
427
+ // gas_for_l2_call_data = payload_size * gas_per_byte = 100 * 16 = 1600
428
+ // l2_fee = (gas_for_l2_call_data + gas) * gas_price_in_unit = (1600 + 50000) * 10e9 =
429
+ // 516_000_000_000_000
430
+ //
431
+ // L1 fee
432
+ // gas_for_l1_call_data = (payload_size * gas_per_byte) + 3188 = (100 * 0) + 3188 = 3188
433
+ // l1_fee = gas_for_l1_call_data * gas_price_in_unit = 3188 * 20e9 = 63_760_000_000_000
434
+ //
435
+ // Total fee
436
+ // total_fee = l1_fee + l2_fee = 516_000_000_000_000 + 63_760_000_000_000 = 579_760_000_000_000
437
+ let expected_estimate = GetFeeResponse {
438
+ gas_fee: 579_760_000_000_000,
439
+ price_ratio: l2_price.price_ratio,
440
+ price_ratio_denominator: PRICE_RATIO_DENOMINATOR,
441
+ native_price_usd: 0,
442
+ };
443
+
444
+ // Check that the fee estimate is correct
445
+ assert_eq!(estimate, expected_estimate);
446
+ }
447
+
448
+
449
+ #[test]
450
+ #[fuzzer(runs: 10)]
451
+ fn should_estimate_fee_with_arbitrum_model(
452
+ owner: ContractAddress, price_updater: ContractAddress, eid: Eid, price: Price,
453
+ ) {
454
+ let eid = eid.eid;
455
+ let normal_eid = eid % MAX_V1_EID;
456
+ let calldata_size: u32 = 100;
457
+ let gas: u256 = 50000;
458
+
459
+ let price = UpdatePriceExt {
460
+ eid: normal_eid,
461
+ price: Price {
462
+ gas_price_in_unit: TEN_GWEI, gas_per_byte: 0, price_ratio: PRICE_RATIO_DENOMINATOR,
463
+ },
464
+ extend: ArbitrumPriceExt { gas_per_l2_tx: 1_000_000, gas_per_l1_call_data_byte: 16 },
465
+ };
466
+ let model_params = array![
467
+ SetEidToModelTypeParam { eid: normal_eid, model_type: ModelType::ARB_STACK },
468
+ ];
469
+ let PriceFeedDeploy {
470
+ price_feed, dispatcher, layer_zero, ..,
471
+ } = deploy_price_feed(owner, price_updater);
472
+
473
+ // Caller is the owner
474
+ start_cheat_caller_address(price_feed, owner);
475
+ dispatcher.set_eid_to_model_type(model_params);
476
+ dispatcher.set_price_for_arbitrum(price.clone());
477
+ stop_cheat_caller_address(price_feed);
478
+
479
+ // Check that the model type is set correctly
480
+ assert_eq!(dispatcher.get_eid_to_model_type(normal_eid), ModelType::ARB_STACK);
481
+
482
+ // Estimate fee
483
+ let estimate = layer_zero.estimate_fee_on_send(eid, calldata_size, gas);
484
+
485
+ // gas_for_l1_call_data = ((payload_size * arbitrum_compression_percent) / 100) *
486
+ // gas_per_l1_call_data_byte gas_for_l1_call_data = ((100 * 47) / 100) * 16 = 752
487
+ // gas_for_l2_call_data = payload_size * gas_per_byte = 100 * 0 = 0
488
+ // total_gas = gas + gas_per_l2_tx + gas_for_l1_call_data + gas_for_l2_call_data
489
+ // total_gas = 50000 + 1_000_000 + 752 + 0 = 1_050_752
490
+ // fee = total_gas * gas_price_in_unit = 1_050_752 * 10_000_000_000 = 10_507_520_000_000_000
491
+ let expected_estimate = GetFeeResponse {
492
+ gas_fee: 10_507_520_000_000_000,
493
+ price_ratio: price.price.price_ratio,
494
+ price_ratio_denominator: PRICE_RATIO_DENOMINATOR,
495
+ native_price_usd: 0,
496
+ };
497
+
498
+ // Check that the fee estimate is correct
499
+ assert_eq!(estimate, expected_estimate);
500
+ }
501
+
502
+ #[test]
503
+ #[fuzzer(runs: 10)]
504
+ fn should_set_price_for_arbitrum_by_price_updater(
505
+ owner: ContractAddress,
506
+ price_updater: ContractAddress,
507
+ eid: Eid,
508
+ price: Price,
509
+ extend: ArbitrumPriceExt,
510
+ ) {
511
+ let eid = eid.eid;
512
+ let price = UpdatePriceExt { eid, price, extend: extend.clone() };
513
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(owner, price_updater);
514
+
515
+ // Caller is the price updater
516
+ start_cheat_caller_address(price_feed, price_updater);
517
+ dispatcher.set_price_for_arbitrum(price.clone());
518
+ stop_cheat_caller_address(price_feed);
519
+
520
+ // Check that the price is set correctly
521
+ assert_eq!(dispatcher.get_price_arbitrum_ext(eid), extend);
522
+ }
523
+
524
+ #[test]
525
+ #[fuzzer(runs: 10)]
526
+ #[feature("safe_dispatcher")]
527
+ fn should_fail_to_set_price_for_arbitrum_when_not_price_updater_or_owner(
528
+ owner: ContractAddress,
529
+ not_price_updater_or_owner: ContractAddress,
530
+ price_updater: ContractAddress,
531
+ eid: Eid,
532
+ price: Price,
533
+ extend: ArbitrumPriceExt,
534
+ ) {
535
+ let eid = eid.eid;
536
+ let price = UpdatePriceExt { eid, price, extend: extend.clone() };
537
+ let PriceFeedDeploy {
538
+ price_feed, safe_dispatcher, ..,
539
+ } = deploy_price_feed(owner, price_updater);
540
+
541
+ // Caller is not the price updater or the owner
542
+ start_cheat_caller_address(price_feed, not_price_updater_or_owner);
543
+ let res = safe_dispatcher.set_price_for_arbitrum(price);
544
+ stop_cheat_caller_address(price_feed);
545
+
546
+ // Check that set_price_for_arbitrum panics with the expected error
547
+ assert_panic_with_error(res, err_lz_price_feed_only_price_updater());
548
+ }
549
+
550
+ #[test]
551
+ #[fuzzer(runs: 10)]
552
+ fn should_update_price_and_reestimate_fee(
553
+ owner: ContractAddress, price_updater: ContractAddress, eid: Eid, price: Price,
554
+ ) {
555
+ let PriceFeedDeploy {
556
+ price_feed, dispatcher, layer_zero, ..,
557
+ } = deploy_price_feed(owner, price_updater);
558
+
559
+ let eid = eid.eid;
560
+ let calldata_size: u32 = 100;
561
+ let gas: u256 = 50000;
562
+
563
+ // First price
564
+ let price_1 = Price {
565
+ gas_price_in_unit: TEN_GWEI, gas_per_byte: 16, price_ratio: 2 * PRICE_RATIO_DENOMINATOR,
566
+ };
567
+ let params_1 = array![SetPriceParam { eid: eid % MAX_V1_EID, price: price_1.clone() }];
568
+
569
+ // Caller is the owner
570
+ start_cheat_caller_address(price_feed, owner);
571
+ dispatcher.set_price(params_1);
572
+ stop_cheat_caller_address(price_feed);
573
+
574
+ let estimate_1 = layer_zero.estimate_fee_on_send(eid, calldata_size, gas);
575
+ let expected_estimate_1 = GetFeeResponse {
576
+ gas_fee: 1_032_000_000_000_000,
577
+ price_ratio: price_1.price_ratio,
578
+ price_ratio_denominator: PRICE_RATIO_DENOMINATOR,
579
+ native_price_usd: 0,
580
+ };
581
+ assert_eq!(estimate_1, expected_estimate_1);
582
+
583
+ // Second price
584
+ let price_2 = Price {
585
+ gas_price_in_unit: 2 * TEN_GWEI, gas_per_byte: 32, price_ratio: 3 * PRICE_RATIO_DENOMINATOR,
586
+ };
587
+ let params_2 = array![SetPriceParam { eid: eid % MAX_V1_EID, price: price_2.clone() }];
588
+
589
+ // Caller is the owner
590
+ start_cheat_caller_address(price_feed, owner);
591
+ dispatcher.set_price(params_2);
592
+ stop_cheat_caller_address(price_feed);
593
+
594
+ let estimate_2 = layer_zero.estimate_fee_on_send(eid, calldata_size, gas);
595
+
596
+ // gas_for_call_data = 100 * 32 = 3200
597
+ // remote_fee = (3200 + 50000) * 20_000_000_000 = 1_064_000_000_000_000
598
+ // expected_gas_fee = 1_064_000_000_000_000 * 3 = 3_192_000_000_000_000
599
+ let expected_estimate_2 = GetFeeResponse {
600
+ gas_fee: 3_192_000_000_000_000,
601
+ price_ratio: price_2.price_ratio,
602
+ price_ratio_denominator: PRICE_RATIO_DENOMINATOR,
603
+ native_price_usd: 0,
604
+ };
605
+ assert_eq!(estimate_2, expected_estimate_2);
606
+ }
607
+
608
+
609
+ #[test]
610
+ #[fuzzer(runs: 10)]
611
+ fn should_view_estimate_fee_by_eid(
612
+ owner: ContractAddress, price_updater: ContractAddress, eid: Eid, price: Price,
613
+ ) {
614
+ let eid = eid.eid;
615
+ let calldata_size: u32 = 100;
616
+ let gas: u256 = 50000;
617
+
618
+ let price = Price {
619
+ gas_price_in_unit: TEN_GWEI, gas_per_byte: 16, price_ratio: 2 * PRICE_RATIO_DENOMINATOR,
620
+ };
621
+ let params = array![SetPriceParam { eid: eid % MAX_V1_EID, price: price.clone() }];
622
+ let PriceFeedDeploy {
623
+ price_feed, dispatcher, layer_zero, ..,
624
+ } = deploy_price_feed(owner, price_updater);
625
+
626
+ // Caller is the owner
627
+ start_cheat_caller_address(price_feed, owner);
628
+ dispatcher.set_price(params);
629
+ stop_cheat_caller_address(price_feed);
630
+
631
+ let estimate = layer_zero.estimate_fee_by_eid(eid, calldata_size, gas);
632
+
633
+ // gas_for_call_data = calldata_size * gas_per_byte = 100 * 16 = 1600
634
+ // remote_fee = (gas_for_call_data + gas) * gas_price_in_unit
635
+ // remote_fee = (1600 + 50000) * 10_000_000_000 = 516_000_000_000_000
636
+ // expected_gas_fee = remote_fee * price_ratio / PRICE_RATIO_DENOMINATOR
637
+ // expected_gas_fee = 516_000_000_000_000 * 200000000000000000000 / 100000000000000000000 =
638
+ let expected_estimate = GetFeeResponse {
639
+ gas_fee: 1_032_000_000_000_000,
640
+ price_ratio: price.price_ratio,
641
+ price_ratio_denominator: PRICE_RATIO_DENOMINATOR,
642
+ native_price_usd: 0,
643
+ };
644
+
645
+ // Check that the fee estimate is correct
646
+ assert_eq!(estimate, expected_estimate);
647
+ }
648
+
649
+ #[test]
650
+ #[fuzzer(runs: 10)]
651
+ fn should_deploy_with_price_ratio_denominator(
652
+ owner: ContractAddress, price_updater: ContractAddress,
653
+ ) {
654
+ let PriceFeedDeploy { layer_zero, .. } = deploy_price_feed(owner, price_updater);
655
+
656
+ // Check that the price ratio denominator is set correctly
657
+ assert_eq!(layer_zero.get_price_ratio_denominator(), PRICE_RATIO_DENOMINATOR);
658
+ }
659
+
660
+ #[test]
661
+ fn should_set_native_price_usd_as_owner() {
662
+ let PriceFeedDeploy {
663
+ price_feed, dispatcher, layer_zero, ..,
664
+ } = deploy_price_feed(OWNER, PRICE_UPDATER);
665
+
666
+ // Caller is the owner
667
+ start_cheat_caller_address(price_feed, OWNER);
668
+ dispatcher.set_native_price_usd(NATIVE_PRICE_USD);
669
+ stop_cheat_caller_address(price_feed);
670
+
671
+ // Check that the native price usd is set correctly as the owner
672
+ assert(layer_zero.native_price_usd() == NATIVE_PRICE_USD, 'native price usd should be set');
673
+ }
674
+
675
+ #[test]
676
+ fn should_set_native_price_usd_as_updater() {
677
+ let PriceFeedDeploy {
678
+ price_feed, dispatcher, layer_zero, ..,
679
+ } = deploy_price_feed(OWNER, PRICE_UPDATER);
680
+
681
+ // Caller is not the owner
682
+ start_cheat_caller_address(price_feed, PRICE_UPDATER);
683
+ dispatcher.set_native_price_usd(NATIVE_PRICE_USD);
684
+ stop_cheat_caller_address(price_feed);
685
+
686
+ // Check that the native price usd is set correctly as the price updater
687
+ assert(layer_zero.native_price_usd() == NATIVE_PRICE_USD, 'native price usd should be set');
688
+ }
689
+
690
+ #[test]
691
+ fn should_set_price_ratio_denominator() {
692
+ let PriceFeedDeploy {
693
+ price_feed, dispatcher, layer_zero, ..,
694
+ } = deploy_price_feed(OWNER, PRICE_UPDATER);
695
+
696
+ // Caller is the owner
697
+ start_cheat_caller_address(price_feed, OWNER);
698
+ dispatcher.set_price_ratio_denominator(PRICE_RATIO_DENOMINATOR);
699
+ stop_cheat_caller_address(price_feed);
700
+
701
+ // Check that the price ratio denominator is set correctly
702
+ assert(
703
+ layer_zero.get_price_ratio_denominator() == PRICE_RATIO_DENOMINATOR,
704
+ 'price ratio denom should be set',
705
+ );
706
+ }
707
+
708
+ #[test]
709
+ #[feature("safe_dispatcher")]
710
+ fn should_fail_to_set_price_ratio_denominator_when_not_owner() {
711
+ let PriceFeedDeploy {
712
+ price_feed, safe_dispatcher, ..,
713
+ } = deploy_price_feed(OWNER, PRICE_UPDATER);
714
+
715
+ // Caller is not the owner
716
+ start_cheat_caller_address(price_feed, PRICE_UPDATER);
717
+ let res = safe_dispatcher.set_price_ratio_denominator(PRICE_RATIO_DENOMINATOR);
718
+ stop_cheat_caller_address(price_feed);
719
+
720
+ // Check that set_arbitrum_compression_percent panics with the expected error
721
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
722
+ }
723
+
724
+ #[test]
725
+ fn should_set_arbitrum_compression_percent() {
726
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(OWNER, PRICE_UPDATER);
727
+
728
+ // Caller is the owner
729
+ start_cheat_caller_address(price_feed, OWNER);
730
+ dispatcher.set_arbitrum_compression_percent(ARBITRUM_COMPRESSION_PERCENT);
731
+ stop_cheat_caller_address(price_feed);
732
+
733
+ // Check that the arbitrum compression percent is set correctly
734
+ assert(
735
+ dispatcher.get_arbitrum_compression_percent() == ARBITRUM_COMPRESSION_PERCENT,
736
+ 'arb compr percent should be set',
737
+ );
738
+ }
739
+
740
+ #[test]
741
+ #[feature("safe_dispatcher")]
742
+ fn should_fail_to_set_arbitrum_compression_percent_when_not_owner() {
743
+ let PriceFeedDeploy {
744
+ price_feed, safe_dispatcher, ..,
745
+ } = deploy_price_feed(OWNER, PRICE_UPDATER);
746
+
747
+ // Caller is not the owner
748
+ start_cheat_caller_address(price_feed, PRICE_UPDATER);
749
+ let res = safe_dispatcher.set_arbitrum_compression_percent(100);
750
+ stop_cheat_caller_address(price_feed);
751
+
752
+ // Check that set_arbitrum_compression_percent panics with the expected error
753
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
754
+ }
755
+
756
+
757
+ #[test]
758
+ fn should_set_endpoint() {
759
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(OWNER, PRICE_UPDATER);
760
+
761
+ // Caller is the owner
762
+ start_cheat_caller_address(price_feed, OWNER);
763
+ dispatcher.set_endpoint(ENDPOINT);
764
+ stop_cheat_caller_address(price_feed);
765
+
766
+ // Check that the endpoint is set correctly
767
+ assert(dispatcher.get_endpoint() == ENDPOINT, 'endpoint should be set');
768
+ }
769
+
770
+ #[test]
771
+ #[feature("safe_dispatcher")]
772
+ fn should_fail_to_set_endpoint_when_not_owner() {
773
+ let PriceFeedDeploy {
774
+ price_feed, safe_dispatcher, ..,
775
+ } = deploy_price_feed(OWNER, PRICE_UPDATER);
776
+
777
+ // Caller is the owner
778
+ start_cheat_caller_address(price_feed, PRICE_UPDATER);
779
+ let res = safe_dispatcher.set_endpoint(ENDPOINT);
780
+ stop_cheat_caller_address(price_feed);
781
+
782
+ // Check that the endpoint is set correctly
783
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
784
+ }
785
+ #[test]
786
+ #[fuzzer(runs: 10)]
787
+ fn should_withdraw_fee(owner: ContractAddress, price_updater: ContractAddress, amount: u256) {
788
+ let PriceFeedDeploy { price_feed, dispatcher, .. } = deploy_price_feed(owner, price_updater);
789
+
790
+ // Feed price feed with tokens
791
+ let ERC20Mock { token, token_dispatcher } = deploy_mock_erc20(amount, price_feed);
792
+
793
+ let mut spy = spy_events();
794
+
795
+ // Owner withdraws fee
796
+ start_cheat_caller_address(price_feed, owner);
797
+ dispatcher.withdraw_fee(token, owner, amount);
798
+ stop_cheat_caller_address(price_feed);
799
+
800
+ // Check that the fee is withdrawn correctly
801
+ assert(token_dispatcher.balance_of(owner) == amount, 'fee should be withdrawn');
802
+ assert(token_dispatcher.balance_of(price_feed) == 0, 'price feed balance should be 0');
803
+
804
+ // Verify WithdrawFee event was emitted
805
+ let price_feed_event = PriceFeedEvent::FeeWithdrawn(
806
+ FeeWithdrawn { token_address: token, to: owner, amount: amount },
807
+ );
808
+ spy.assert_emitted(@array![(price_feed, price_feed_event)]);
809
+
810
+ // Verify ERC20 transfer event was emitted
811
+ let erc20_event = ERC20Event::Transfer(Transfer { from: price_feed, to: owner, value: amount });
812
+ spy.assert_emitted(@array![(token, erc20_event)]);
813
+ }
814
+
815
+ #[test]
816
+ #[fuzzer(runs: 10)]
817
+ #[feature("safe_dispatcher")]
818
+ fn should_fail_withdraw_fee_when_insufficient_balance(
819
+ owner: ContractAddress,
820
+ price_updater: ContractAddress,
821
+ amount: u256,
822
+ token_holder: ContractAddress,
823
+ ) {
824
+ let PriceFeedDeploy {
825
+ price_feed, safe_dispatcher, ..,
826
+ } = deploy_price_feed(owner, price_updater);
827
+
828
+ // Feed price feed with 0 tokens
829
+ let ERC20Mock { token, token_dispatcher } = deploy_mock_erc20(0, price_feed);
830
+
831
+ // Owner tries to withdraw fee
832
+ start_cheat_caller_address(price_feed, owner);
833
+ let res = safe_dispatcher.withdraw_fee(token, owner, amount);
834
+ stop_cheat_caller_address(price_feed);
835
+
836
+ // Check that the fee has not been withdrawn
837
+ assert_panic_with_felt_error(res, ERC20Errors::INSUFFICIENT_BALANCE);
838
+ assert(token_dispatcher.balance_of(owner) == 0, 'owner balance should be 0');
839
+ }
840
+
841
+ #[test]
842
+ #[fuzzer(runs: 10)]
843
+ #[feature("safe_dispatcher")]
844
+ fn should_fail_withdraw_fee_when_not_owner(
845
+ owner: ContractAddress,
846
+ not_owner: ContractAddress,
847
+ price_updater: ContractAddress,
848
+ amount: u256,
849
+ token_holder: ContractAddress,
850
+ ) {
851
+ let PriceFeedDeploy {
852
+ price_feed, safe_dispatcher, ..,
853
+ } = deploy_price_feed(owner, price_updater);
854
+
855
+ // Feed price feed with tokens
856
+ let ERC20Mock { token, token_dispatcher } = deploy_mock_erc20(amount, price_feed);
857
+
858
+ // Not owner tries to withdraw fee
859
+ start_cheat_caller_address(price_feed, not_owner);
860
+ let res = safe_dispatcher.withdraw_fee(token, not_owner, amount);
861
+ stop_cheat_caller_address(price_feed);
862
+
863
+ // Check that the fee has not been withdrawn
864
+ assert_panic_with_felt_error(res, OwnableComponent::Errors::NOT_OWNER);
865
+ assert(token_dispatcher.balance_of(price_feed) == amount, 'pfeed balance unchanged');
866
+ assert(token_dispatcher.balance_of(not_owner) == 0, 'not owner balance should be 0');
867
+ }
868
+
869
+ //////////////////////////
870
+ // Implementation tests //
871
+ //////////////////////////
872
+
873
+ #[test]
874
+ fn impl_layer_zero_price_feed() {
875
+ let PriceFeedDeploy { price_feed, .. } = deploy_price_feed(OWNER, PRICE_UPDATER);
876
+
877
+ /// Runtime check that the price feed implements the ILayerZeroPriceFeed trait
878
+ ILayerZeroPriceFeedDispatcher { contract_address: price_feed };
879
+ }