@layerzerolabs/protocol-stellar-v2 0.2.8

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 (265) hide show
  1. package/.turbo/turbo-build.log +727 -0
  2. package/.turbo/turbo-lint.log +158 -0
  3. package/.turbo/turbo-test.log +796 -0
  4. package/Cargo.lock +2237 -0
  5. package/Cargo.toml +63 -0
  6. package/clippy.toml +7 -0
  7. package/contracts/common-macros/Cargo.toml +20 -0
  8. package/contracts/common-macros/src/error.rs +53 -0
  9. package/contracts/common-macros/src/event.rs +16 -0
  10. package/contracts/common-macros/src/lib.rs +255 -0
  11. package/contracts/common-macros/src/ownable.rs +63 -0
  12. package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +310 -0
  13. package/contracts/common-macros/src/storage.rs +439 -0
  14. package/contracts/common-macros/src/tests.rs +287 -0
  15. package/contracts/common-macros/src/ttl_configurable.rs +60 -0
  16. package/contracts/endpoint-v2/ARCHITECTURE.md +233 -0
  17. package/contracts/endpoint-v2/Cargo.toml +30 -0
  18. package/contracts/endpoint-v2/src/constants.rs +52 -0
  19. package/contracts/endpoint-v2/src/endpoint_v2.rs +305 -0
  20. package/contracts/endpoint-v2/src/errors.rs +29 -0
  21. package/contracts/endpoint-v2/src/events.rs +207 -0
  22. package/contracts/endpoint-v2/src/interfaces/layerzero_composer.rs +26 -0
  23. package/contracts/endpoint-v2/src/interfaces/layerzero_endpoint_v2.rs +170 -0
  24. package/contracts/endpoint-v2/src/interfaces/layerzero_receiver.rs +43 -0
  25. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +62 -0
  26. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +220 -0
  27. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +121 -0
  28. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +63 -0
  29. package/contracts/endpoint-v2/src/interfaces/mod.rs +17 -0
  30. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +70 -0
  31. package/contracts/endpoint-v2/src/lib.rs +22 -0
  32. package/contracts/endpoint-v2/src/message_lib_manager.rs +315 -0
  33. package/contracts/endpoint-v2/src/messaging_channel.rs +218 -0
  34. package/contracts/endpoint-v2/src/messaging_composer.rs +76 -0
  35. package/contracts/endpoint-v2/src/storage.rs +78 -0
  36. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +131 -0
  37. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +237 -0
  38. package/contracts/endpoint-v2/src/tests/endpoint_v2/delegate.rs +42 -0
  39. package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +76 -0
  40. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +211 -0
  41. package/contracts/endpoint-v2/src/tests/endpoint_v2/mod.rs +18 -0
  42. package/contracts/endpoint-v2/src/tests/endpoint_v2/native_token.rs +10 -0
  43. package/contracts/endpoint-v2/src/tests/endpoint_v2/owner.rs +10 -0
  44. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +424 -0
  45. package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +144 -0
  46. package/contracts/endpoint-v2/src/tests/endpoint_v2/recover_token.rs +72 -0
  47. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +29 -0
  48. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +513 -0
  49. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +43 -0
  50. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +27 -0
  51. package/contracts/endpoint-v2/src/tests/endpoint_v2/transfer_ownership.rs +30 -0
  52. package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +202 -0
  53. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +59 -0
  54. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +172 -0
  55. package/contracts/endpoint-v2/src/tests/endpoint_v2/zro.rs +23 -0
  56. package/contracts/endpoint-v2/src/tests/message_lib_manager/mod.rs +10 -0
  57. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +131 -0
  58. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +35 -0
  59. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +28 -0
  60. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_config.rs +79 -0
  61. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +246 -0
  62. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +285 -0
  63. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +180 -0
  64. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +405 -0
  65. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +80 -0
  66. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +131 -0
  67. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +358 -0
  68. package/contracts/endpoint-v2/src/tests/messaging_channel/clear.rs +316 -0
  69. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +288 -0
  70. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +316 -0
  71. package/contracts/endpoint-v2/src/tests/messaging_channel/internal.rs +388 -0
  72. package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +307 -0
  73. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +10 -0
  74. package/contracts/endpoint-v2/src/tests/messaging_channel/next_guid.rs +239 -0
  75. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +324 -0
  76. package/contracts/endpoint-v2/src/tests/messaging_channel/outbound_nonce.rs +242 -0
  77. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +232 -0
  78. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +212 -0
  79. package/contracts/endpoint-v2/src/tests/messaging_composer/compose_queue.rs +213 -0
  80. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +269 -0
  81. package/contracts/endpoint-v2/src/tests/messaging_composer/mod.rs +4 -0
  82. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +173 -0
  83. package/contracts/endpoint-v2/src/tests/mock.rs +132 -0
  84. package/contracts/endpoint-v2/src/tests/mod.rs +12 -0
  85. package/contracts/endpoint-v2/src/tests/util/build_payload.rs +126 -0
  86. package/contracts/endpoint-v2/src/tests/util/compute_guid.rs +82 -0
  87. package/contracts/endpoint-v2/src/tests/util/keccak256.rs +115 -0
  88. package/contracts/endpoint-v2/src/tests/util/mod.rs +3 -0
  89. package/contracts/endpoint-v2/src/util.rs +52 -0
  90. package/contracts/message-libs/Cargo.toml +12 -0
  91. package/contracts/message-libs/block-message-lib/Cargo.toml +19 -0
  92. package/contracts/message-libs/block-message-lib/src/lib.rs +70 -0
  93. package/contracts/message-libs/lib.rs +2 -0
  94. package/contracts/message-libs/message-lib-common/Cargo.toml +24 -0
  95. package/contracts/message-libs/message-lib-common/src/errors.rs +20 -0
  96. package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +55 -0
  97. package/contracts/message-libs/message-lib-common/src/interfaces/executor.rs +46 -0
  98. package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +7 -0
  99. package/contracts/message-libs/message-lib-common/src/interfaces/treasury.rs +17 -0
  100. package/contracts/message-libs/message-lib-common/src/lib.rs +14 -0
  101. package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +99 -0
  102. package/contracts/message-libs/message-lib-common/src/testing_utils.rs +27 -0
  103. package/contracts/message-libs/message-lib-common/src/tests/mod.rs +2 -0
  104. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +162 -0
  105. package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +319 -0
  106. package/contracts/message-libs/message-lib-common/src/worker_options.rs +190 -0
  107. package/contracts/message-libs/simple-message-lib/Cargo.toml +26 -0
  108. package/contracts/message-libs/simple-message-lib/src/errors.rs +11 -0
  109. package/contracts/message-libs/simple-message-lib/src/lib.rs +14 -0
  110. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +136 -0
  111. package/contracts/message-libs/simple-message-lib/src/storage.rs +27 -0
  112. package/contracts/message-libs/simple-message-lib/src/test.rs +280 -0
  113. package/contracts/message-libs/treasury/Cargo.toml +27 -0
  114. package/contracts/message-libs/treasury/src/errors.rs +10 -0
  115. package/contracts/message-libs/treasury/src/events.rs +28 -0
  116. package/contracts/message-libs/treasury/src/interfaces/mod.rs +3 -0
  117. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +20 -0
  118. package/contracts/message-libs/treasury/src/lib.rs +20 -0
  119. package/contracts/message-libs/treasury/src/storage.rs +18 -0
  120. package/contracts/message-libs/treasury/src/tests/mod.rs +2 -0
  121. package/contracts/message-libs/treasury/src/tests/setup.rs +112 -0
  122. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +562 -0
  123. package/contracts/message-libs/treasury/src/treasury.rs +140 -0
  124. package/contracts/message-libs/uln-302/Cargo.toml +28 -0
  125. package/contracts/message-libs/uln-302/src/config_validation.rs +173 -0
  126. package/contracts/message-libs/uln-302/src/errors.rs +29 -0
  127. package/contracts/message-libs/uln-302/src/events.rs +72 -0
  128. package/contracts/message-libs/uln-302/src/interfaces/mod.rs +5 -0
  129. package/contracts/message-libs/uln-302/src/interfaces/receive.rs +82 -0
  130. package/contracts/message-libs/uln-302/src/interfaces/send.rs +159 -0
  131. package/contracts/message-libs/uln-302/src/lib.rs +20 -0
  132. package/contracts/message-libs/uln-302/src/receive.rs +199 -0
  133. package/contracts/message-libs/uln-302/src/send.rs +349 -0
  134. package/contracts/message-libs/uln-302/src/storage.rs +47 -0
  135. package/contracts/message-libs/uln-302/src/tests/config/mod.rs +2 -0
  136. package/contracts/message-libs/uln-302/src/tests/config/oapp_uln_config.rs +291 -0
  137. package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +163 -0
  138. package/contracts/message-libs/uln-302/src/tests/mod.rs +7 -0
  139. package/contracts/message-libs/uln-302/src/tests/receive_uln302/commit_verification.rs +183 -0
  140. package/contracts/message-libs/uln-302/src/tests/receive_uln302/confirmations.rs +128 -0
  141. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +104 -0
  142. package/contracts/message-libs/uln-302/src/tests/receive_uln302/mod.rs +66 -0
  143. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +79 -0
  144. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +463 -0
  145. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +173 -0
  146. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +132 -0
  147. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +117 -0
  148. package/contracts/message-libs/uln-302/src/tests/send_uln302/mod.rs +6 -0
  149. package/contracts/message-libs/uln-302/src/tests/send_uln302/quote.rs +586 -0
  150. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +834 -0
  151. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +95 -0
  152. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +80 -0
  153. package/contracts/message-libs/uln-302/src/tests/setup.rs +268 -0
  154. package/contracts/message-libs/uln-302/src/tests/testing_utils.rs +47 -0
  155. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_receive_uln_config.rs +51 -0
  156. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_send_uln_config.rs +51 -0
  157. package/contracts/message-libs/uln-302/src/tests/uln302/get_oapp_executor_config.rs +48 -0
  158. package/contracts/message-libs/uln-302/src/tests/uln302/mod.rs +4 -0
  159. package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +998 -0
  160. package/contracts/message-libs/uln-302/src/uln302.rs +117 -0
  161. package/contracts/oapp-macros/Cargo.toml +21 -0
  162. package/contracts/oapp-macros/src/lib.rs +408 -0
  163. package/contracts/oapp-macros/src/oapp_core.rs +49 -0
  164. package/contracts/oapp-macros/src/oapp_full.rs +15 -0
  165. package/contracts/oapp-macros/src/oapp_options_type3.rs +46 -0
  166. package/contracts/oapp-macros/src/oapp_receiver.rs +67 -0
  167. package/contracts/oapp-macros/src/oapp_sender.rs +23 -0
  168. package/contracts/oapp-macros/src/util.rs +103 -0
  169. package/contracts/oapp-macros/tests/test_macros.rs +522 -0
  170. package/contracts/oapps/Cargo.toml +12 -0
  171. package/contracts/oapps/counter/Cargo.toml +24 -0
  172. package/contracts/oapps/counter/integration_tests/mod.rs +3 -0
  173. package/contracts/oapps/counter/integration_tests/setup.rs +201 -0
  174. package/contracts/oapps/counter/integration_tests/test_with_sml.rs +166 -0
  175. package/contracts/oapps/counter/integration_tests/utils.rs +144 -0
  176. package/contracts/oapps/counter/src/codec.rs +63 -0
  177. package/contracts/oapps/counter/src/counter.rs +235 -0
  178. package/contracts/oapps/counter/src/errors.rs +9 -0
  179. package/contracts/oapps/counter/src/lib.rs +16 -0
  180. package/contracts/oapps/counter/src/options.rs +30 -0
  181. package/contracts/oapps/counter/src/storage.rs +33 -0
  182. package/contracts/oapps/counter/src/tests/mod.rs +37 -0
  183. package/contracts/oapps/counter/src/tests/test_codec.rs +64 -0
  184. package/contracts/oapps/counter/src/tests/test_counter.rs +390 -0
  185. package/contracts/oapps/counter/src/u256_ext.rs +21 -0
  186. package/contracts/oapps/lib.rs +2 -0
  187. package/contracts/oapps/oapp/Cargo.toml +21 -0
  188. package/contracts/oapps/oapp/src/errors.rs +9 -0
  189. package/contracts/oapps/oapp/src/lib.rs +10 -0
  190. package/contracts/oapps/oapp/src/oapp_core.rs +92 -0
  191. package/contracts/oapps/oapp/src/oapp_options_type3.rs +89 -0
  192. package/contracts/oapps/oapp/src/oapp_receiver.rs +72 -0
  193. package/contracts/oapps/oapp/src/oapp_sender.rs +66 -0
  194. package/contracts/oapps/oapp/src/tests/mod.rs +4 -0
  195. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +162 -0
  196. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +180 -0
  197. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +157 -0
  198. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +283 -0
  199. package/contracts/utils/Cargo.toml +21 -0
  200. package/contracts/utils/src/buffer_reader.rs +143 -0
  201. package/contracts/utils/src/buffer_writer.rs +117 -0
  202. package/contracts/utils/src/bytes_ext.rs +19 -0
  203. package/contracts/utils/src/errors.rs +30 -0
  204. package/contracts/utils/src/lib.rs +15 -0
  205. package/contracts/utils/src/option_ext.rs +38 -0
  206. package/contracts/utils/src/ownable.rs +88 -0
  207. package/contracts/utils/src/testing_utils.rs +100 -0
  208. package/contracts/utils/src/tests/buffer_reader.rs +1006 -0
  209. package/contracts/utils/src/tests/buffer_writer.rs +330 -0
  210. package/contracts/utils/src/tests/bytes_ext.rs +77 -0
  211. package/contracts/utils/src/tests/mod.rs +4 -0
  212. package/contracts/utils/src/tests/ownable.rs +149 -0
  213. package/contracts/utils/src/ttl.rs +164 -0
  214. package/contracts/workers/Cargo.toml +13 -0
  215. package/contracts/workers/executor/Cargo.toml +26 -0
  216. package/contracts/workers/executor/src/events.rs +22 -0
  217. package/contracts/workers/executor/src/executor.rs +347 -0
  218. package/contracts/workers/executor/src/interfaces/executor.rs +40 -0
  219. package/contracts/workers/executor/src/interfaces/mod.rs +5 -0
  220. package/contracts/workers/executor/src/interfaces/types.rs +51 -0
  221. package/contracts/workers/executor/src/lib.rs +10 -0
  222. package/contracts/workers/executor/src/storage.rs +23 -0
  223. package/contracts/workers/lib.rs +2 -0
  224. package/contracts/workers/worker-common/Cargo.toml +18 -0
  225. package/contracts/workers/worker-common/src/constants.rs +17 -0
  226. package/contracts/workers/worker-common/src/errors.rs +6 -0
  227. package/contracts/workers/worker-common/src/events.rs +34 -0
  228. package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +35 -0
  229. package/contracts/workers/worker-common/src/interfaces/mod.rs +7 -0
  230. package/contracts/workers/worker-common/src/interfaces/price_feed.rs +40 -0
  231. package/contracts/workers/worker-common/src/interfaces/worker.rs +60 -0
  232. package/contracts/workers/worker-common/src/lib.rs +19 -0
  233. package/contracts/workers/worker-common/src/storage.rs +32 -0
  234. package/contracts/workers/worker-common/src/worker_common.rs +166 -0
  235. package/package.json +25 -0
  236. package/rust-toolchain.toml +4 -0
  237. package/rustfmt.toml +17 -0
  238. package/sdk/.turbo/turbo-build.log +4 -0
  239. package/sdk/dist/generated/bml.d.ts +452 -0
  240. package/sdk/dist/generated/bml.js +72 -0
  241. package/sdk/dist/generated/counter.d.ts +824 -0
  242. package/sdk/dist/generated/counter.js +125 -0
  243. package/sdk/dist/generated/endpoint.d.ts +1676 -0
  244. package/sdk/dist/generated/endpoint.js +216 -0
  245. package/sdk/dist/generated/sml.d.ts +810 -0
  246. package/sdk/dist/generated/sml.js +132 -0
  247. package/sdk/dist/generated/uln302.d.ts +1227 -0
  248. package/sdk/dist/generated/uln302.js +185 -0
  249. package/sdk/dist/index.d.ts +5 -0
  250. package/sdk/dist/index.js +5 -0
  251. package/sdk/node_modules/.bin/tsc +21 -0
  252. package/sdk/node_modules/.bin/tsserver +21 -0
  253. package/sdk/node_modules/.bin/vitest +21 -0
  254. package/sdk/node_modules/.bin/zx +21 -0
  255. package/sdk/package.json +40 -0
  256. package/sdk/src/index.ts +5 -0
  257. package/sdk/test/index.test.ts +271 -0
  258. package/sdk/test/suites/constants.ts +13 -0
  259. package/sdk/test/suites/deploy.ts +277 -0
  260. package/sdk/test/suites/localnet.ts +42 -0
  261. package/sdk/test/suites/scan.ts +189 -0
  262. package/sdk/tsconfig.json +106 -0
  263. package/tools/ts-bindings-gen/Cargo.toml +14 -0
  264. package/tools/ts-bindings-gen/src/main.rs +147 -0
  265. package/turbo.json +12 -0
@@ -0,0 +1,390 @@
1
+ extern crate std;
2
+
3
+ use endpoint_v2::{MessagingFee, MessagingParams, MessagingReceipt, Origin};
4
+ use soroban_sdk::{
5
+ contract, contractimpl, log, symbol_short,
6
+ testutils::{Address as _, MockAuth, MockAuthInvoke},
7
+ Address, Bytes, BytesN, Env, IntoVal, U256,
8
+ };
9
+
10
+ use crate::{
11
+ codec::{self, MsgType},
12
+ counter::{Counter, CounterClient},
13
+ errors::CounterError,
14
+ tests::{approve, mint_to},
15
+ };
16
+
17
+ struct TestSetup<'a> {
18
+ env: Env,
19
+ owner: Address,
20
+ counter: CounterClient<'a>,
21
+ endpoint: Address,
22
+ native_token: Address,
23
+ }
24
+
25
+ #[contract]
26
+ pub struct DummyEndpoint;
27
+
28
+ #[contractimpl]
29
+ impl DummyEndpoint {
30
+ pub fn __constructor(env: Env, native_token: Address) {
31
+ env.storage().instance().set(&symbol_short!("ntk"), &native_token);
32
+ }
33
+
34
+ pub fn set_delegate(_env: Env, _oapp: Address, _delegate: Address) {
35
+ // do nothing
36
+ }
37
+
38
+ pub fn eid(_env: Env) -> u32 {
39
+ 100
40
+ }
41
+
42
+ pub fn native_token(env: Env) -> Address {
43
+ env.storage().instance().get(&symbol_short!("ntk")).unwrap()
44
+ }
45
+
46
+ pub fn send(env: Env, _sender: Address, _params: MessagingParams, _refund_address: Address) -> MessagingReceipt {
47
+ MessagingReceipt {
48
+ guid: BytesN::from_array(&env, &[1u8; 32]),
49
+ nonce: 1,
50
+ fee: MessagingFee { native_fee: 100, zro_fee: 0 },
51
+ }
52
+ }
53
+
54
+ pub fn skip(_env: Env, _caller: Address, _receiver: Address, _src_eid: u32, _sender: BytesN<32>, _nonce: u64) {
55
+ // do nothing
56
+ }
57
+
58
+ pub fn clear(_env: Env, _caller: Address, _origin: Origin, _receiver: Address, _guid: BytesN<32>, _message: Bytes) {
59
+ // do nothing
60
+ }
61
+
62
+ pub fn clear_compose(
63
+ _env: Env,
64
+ _composer: Address,
65
+ _from: Address,
66
+ _guid: BytesN<32>,
67
+ _index: u32,
68
+ _message: Bytes,
69
+ ) {
70
+ // do nothing
71
+ }
72
+ }
73
+
74
+ fn setup<'a>() -> TestSetup<'a> {
75
+ let env = Env::default();
76
+ let owner = Address::generate(&env);
77
+ let sac = env.register_stellar_asset_contract_v2(owner.clone());
78
+
79
+ let endpoint = env.register(DummyEndpoint, (&sac.address(),));
80
+ let counter = env.register(Counter, (&owner, &endpoint, &owner));
81
+ let counter_client = CounterClient::new(&env, &counter);
82
+
83
+ log!(&env, "native_token: {}", sac.address());
84
+ log!(&env, "endpoint: {}", endpoint);
85
+ log!(&env, "counter: {}", counter);
86
+
87
+ TestSetup { env, owner, counter: counter_client, endpoint, native_token: sac.address() }
88
+ }
89
+
90
+ fn setup_mock_peer(env: &Env, owner: &Address, counter: &CounterClient<'_>, dst_eid: u32) -> BytesN<32> {
91
+ let peer = BytesN::from_array(env, &[1u8; 32]);
92
+ env.mock_auths(&[MockAuth {
93
+ address: owner,
94
+ invoke: &MockAuthInvoke {
95
+ contract: &counter.address,
96
+ fn_name: "set_peer",
97
+ args: (&dst_eid, &Some(peer.clone())).into_val(env),
98
+ sub_invokes: &[],
99
+ },
100
+ }]);
101
+ counter.set_peer(&dst_eid, &Some(peer.clone()));
102
+ peer
103
+ }
104
+
105
+ fn set_ordered_nonce(env: &Env, owner: &Address, counter: &CounterClient<'_>, ordered_nonce: bool) {
106
+ env.mock_auths(&[MockAuth {
107
+ address: owner,
108
+ invoke: &MockAuthInvoke {
109
+ contract: &counter.address,
110
+ fn_name: "set_ordered_nonce",
111
+ args: (&ordered_nonce,).into_val(env),
112
+ sub_invokes: &[],
113
+ },
114
+ }]);
115
+
116
+ counter.set_ordered_nonce(&ordered_nonce);
117
+ }
118
+
119
+ // tests for major entry functions
120
+
121
+ #[test]
122
+ fn test_increment() {
123
+ let TestSetup { env, owner, counter, endpoint, native_token, .. } = setup();
124
+
125
+ let sender = Address::generate(&env);
126
+ let dst_eid = 101;
127
+ let msg_type = MsgType::Vanilla;
128
+ let fee = MessagingFee { native_fee: 100, zro_fee: 0 };
129
+
130
+ setup_mock_peer(&env, &owner, &counter, dst_eid);
131
+ mint_to(&env, &owner, &native_token, &sender, fee.native_fee);
132
+
133
+ env.mock_auths(&[MockAuth {
134
+ address: &sender,
135
+ invoke: &MockAuthInvoke {
136
+ contract: &counter.address,
137
+ fn_name: "increment",
138
+ args: (&sender, &dst_eid, &(msg_type as u32), &Bytes::new(&env), &fee).into_val(&env),
139
+ sub_invokes: &[MockAuthInvoke {
140
+ contract: &native_token,
141
+ fn_name: "transfer",
142
+ args: (&sender, &endpoint, &fee.native_fee).into_val(&env),
143
+ sub_invokes: &[],
144
+ }],
145
+ },
146
+ }]);
147
+ counter.increment(&sender, &dst_eid, &(msg_type as u32), &Bytes::new(&env), &fee);
148
+
149
+ assert_eq!(counter.outbound_count(&dst_eid), 1);
150
+ }
151
+
152
+ #[test]
153
+ fn test_lz_receive_vanilla() {
154
+ let TestSetup { env, owner, counter, native_token, .. } = setup();
155
+
156
+ let origin = Origin { src_eid: 101, sender: BytesN::from_array(&env, &[1u8; 32]), nonce: 1 };
157
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
158
+ let value = 100;
159
+ let message = codec::encode_with_value(&env, MsgType::Vanilla, origin.src_eid, U256::from_u32(&env, value));
160
+ let executor = Address::generate(&env);
161
+ let extra_data = Bytes::new(&env);
162
+
163
+ setup_mock_peer(&env, &owner, &counter, origin.src_eid);
164
+
165
+ mint_to(&env, &owner, &native_token, &executor, value as i128);
166
+ approve(&env, &executor, &native_token, value as i128);
167
+
168
+ let sub_invokes_with_transfer = MockAuthInvoke {
169
+ contract: &native_token,
170
+ fn_name: "transfer_from",
171
+ args: (&executor, &executor, &counter.address, &(value as i128)).into_val(&env),
172
+ sub_invokes: &[],
173
+ };
174
+ env.mock_auths(&[MockAuth {
175
+ address: &executor,
176
+ invoke: &MockAuthInvoke {
177
+ contract: &counter.address,
178
+ fn_name: "lz_receive",
179
+ args: (&executor, &origin, &guid, &message, &extra_data, &(value as i128)).into_val(&env),
180
+ sub_invokes: &[sub_invokes_with_transfer],
181
+ },
182
+ }]);
183
+
184
+ counter.lz_receive(&executor, &origin, &guid, &message, &extra_data, &(value as i128));
185
+
186
+ assert_eq!(counter.count(), 1);
187
+ assert_eq!(counter.inbound_count(&origin.src_eid), 1);
188
+ }
189
+
190
+ #[test]
191
+ #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
192
+ fn test_lz_receive_not_from_executor() {
193
+ let TestSetup { env, owner, counter, .. } = setup();
194
+
195
+ let origin = Origin { src_eid: 101, sender: BytesN::from_array(&env, &[1u8; 32]), nonce: 1 };
196
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
197
+ let value = 100;
198
+ let message = codec::encode_with_value(&env, MsgType::Vanilla, origin.src_eid, U256::from_u32(&env, value));
199
+ let executor = Address::generate(&env);
200
+ let extra_data = Bytes::new(&env);
201
+
202
+ setup_mock_peer(&env, &owner, &counter, origin.src_eid);
203
+ counter.lz_receive(&executor, &origin, &guid, &message, &extra_data, &(value as i128));
204
+ }
205
+
206
+ #[test]
207
+ fn test_lz_receive_vanilla_ordered_nonce_wrong_nonce() {
208
+ let TestSetup { env, owner, counter, native_token, .. } = setup();
209
+
210
+ // next nonce should be 1 instead of 999
211
+ let origin = Origin { src_eid: 101, sender: BytesN::from_array(&env, &[1u8; 32]), nonce: 999 };
212
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
213
+ let value = 100;
214
+ let message = codec::encode_with_value(&env, MsgType::Vanilla, origin.src_eid, U256::from_u32(&env, value));
215
+ let executor = Address::generate(&env);
216
+ let extra_data = Bytes::new(&env);
217
+
218
+ setup_mock_peer(&env, &owner, &counter, origin.src_eid);
219
+ mint_to(&env, &owner, &native_token, &executor, value as i128);
220
+ approve(&env, &executor, &native_token, value as i128);
221
+
222
+ let sub_invokes_with_transfer = MockAuthInvoke {
223
+ contract: &native_token,
224
+ fn_name: "transfer_from",
225
+ args: (&executor, &executor, &counter.address, &(value as i128)).into_val(&env),
226
+ sub_invokes: &[],
227
+ };
228
+ set_ordered_nonce(&env, &owner, &counter, true);
229
+
230
+ env.mock_auths(&[MockAuth {
231
+ address: &executor,
232
+ invoke: &MockAuthInvoke {
233
+ contract: &counter.address,
234
+ fn_name: "lz_receive",
235
+ args: (&executor, &origin, &guid, &message, &extra_data, &(value as i128)).into_val(&env),
236
+ sub_invokes: &[sub_invokes_with_transfer],
237
+ },
238
+ }]);
239
+
240
+ let result = counter.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, &(value as i128));
241
+ assert_eq!(result.err().unwrap().ok().unwrap(), CounterError::OAppInvalidNonce.into());
242
+ }
243
+
244
+ #[test]
245
+ fn test_lz_compose() {
246
+ let TestSetup { env, owner, counter, native_token, .. } = setup();
247
+
248
+ let from = Address::generate(&env);
249
+ let origin = Origin { src_eid: 101, sender: BytesN::from_array(&env, &[1u8; 32]), nonce: 1 };
250
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
251
+ let value = 100;
252
+ let message = codec::encode_with_value(&env, MsgType::Composed, origin.src_eid, U256::from_u32(&env, value));
253
+ let executor = Address::generate(&env);
254
+ let extra_data = Bytes::new(&env);
255
+
256
+ mint_to(&env, &owner, &native_token, &executor, value as i128);
257
+ approve(&env, &executor, &native_token, value as i128);
258
+ let sub_invokes_with_transfer = MockAuthInvoke {
259
+ contract: &native_token,
260
+ fn_name: "transfer_from",
261
+ args: (&executor, &executor, &counter.address, &(value as i128)).into_val(&env),
262
+ sub_invokes: &[],
263
+ };
264
+ env.mock_auths(&[MockAuth {
265
+ address: &executor,
266
+ invoke: &MockAuthInvoke {
267
+ contract: &counter.address,
268
+ fn_name: "lz_compose",
269
+ args: (&executor, &from, &guid, &0_u32, &message, &extra_data, &(value as i128)).into_val(&env),
270
+ sub_invokes: &[sub_invokes_with_transfer],
271
+ },
272
+ }]);
273
+
274
+ counter.lz_compose(&executor, &from, &guid, &0, &message, &extra_data, &(value as i128));
275
+
276
+ assert_eq!(counter.composed_count(), 1);
277
+ }
278
+
279
+ #[test]
280
+ #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
281
+ fn test_lz_compose_not_from_executor() {
282
+ let TestSetup { env, counter, .. } = setup();
283
+
284
+ let from = Address::generate(&env);
285
+ let origin = Origin { src_eid: 101, sender: BytesN::from_array(&env, &[1u8; 32]), nonce: 1 };
286
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
287
+ let value = 100;
288
+ let message = codec::encode_with_value(&env, MsgType::Composed, origin.src_eid, U256::from_u32(&env, value));
289
+ let executor = Address::generate(&env);
290
+ let extra_data = Bytes::new(&env);
291
+
292
+ counter.lz_compose(&executor, &from, &guid, &0, &message, &extra_data, &(value as i128));
293
+ }
294
+
295
+ #[test]
296
+ fn test_lz_compose_aba() {
297
+ let TestSetup { env, owner, counter, native_token, .. } = setup();
298
+
299
+ let from = Address::generate(&env);
300
+ let origin = Origin { src_eid: 101, sender: BytesN::from_array(&env, &[1u8; 32]), nonce: 1 };
301
+ let guid = BytesN::from_array(&env, &[2u8; 32]);
302
+ let value = 100;
303
+ let message = codec::encode_with_value(&env, MsgType::ComposedABA, origin.src_eid, U256::from_u32(&env, value));
304
+ let executor = Address::generate(&env);
305
+ let extra_data = Bytes::new(&env);
306
+
307
+ setup_mock_peer(&env, &owner, &counter, origin.src_eid);
308
+ mint_to(&env, &owner, &native_token, &executor, value as i128);
309
+ approve(&env, &executor, &native_token, value as i128);
310
+ let sub_invokes_with_transfer = MockAuthInvoke {
311
+ contract: &native_token,
312
+ fn_name: "transfer_from",
313
+ args: (&executor, &executor, &counter.address, &(value as i128)).into_val(&env),
314
+ sub_invokes: &[],
315
+ };
316
+ env.mock_auths(&[MockAuth {
317
+ address: &executor,
318
+ invoke: &MockAuthInvoke {
319
+ contract: &counter.address,
320
+ fn_name: "lz_compose",
321
+ args: (&executor, &from, &guid, &0_u32, &message, &extra_data, &(value as i128)).into_val(&env),
322
+ sub_invokes: &[sub_invokes_with_transfer],
323
+ },
324
+ }]);
325
+
326
+ counter.lz_compose(&executor, &from, &guid, &0_u32, &message, &extra_data, &(value as i128));
327
+
328
+ assert_eq!(counter.composed_count(), 1);
329
+ assert_eq!(counter.outbound_count(&origin.src_eid), 1);
330
+ }
331
+
332
+ // tests for one step functions
333
+
334
+ #[test]
335
+ fn test_next_nonce() {
336
+ let TestSetup { env, owner, counter, .. } = setup();
337
+
338
+ let src_eid = 101;
339
+ let sender = BytesN::from_array(&env, &[1u8; 32]);
340
+ let nonce = counter.next_nonce(&src_eid, &sender);
341
+ assert_eq!(nonce, 0);
342
+
343
+ set_ordered_nonce(&env, &owner, &counter, true);
344
+ let nonce = counter.next_nonce(&src_eid, &sender);
345
+ assert_eq!(nonce, 1);
346
+ }
347
+
348
+ #[test]
349
+ fn test_skip_inbound_nonce() {
350
+ let TestSetup { env, owner, counter, .. } = setup();
351
+
352
+ let src_eid = 101;
353
+ let sender = BytesN::from_array(&env, &[1u8; 32]);
354
+ let nonce = 1;
355
+
356
+ env.mock_auths(&[MockAuth {
357
+ address: &owner,
358
+ invoke: &MockAuthInvoke {
359
+ contract: &counter.address,
360
+ fn_name: "skip_inbound_nonce",
361
+ args: (&src_eid, &sender, &nonce).into_val(&env),
362
+ sub_invokes: &[],
363
+ },
364
+ }]);
365
+
366
+ counter.skip_inbound_nonce(&src_eid, &sender, &nonce);
367
+ }
368
+
369
+ #[test]
370
+ #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
371
+ fn test_skip_inbound_nonce_no_owner() {
372
+ let TestSetup { env, counter, .. } = setup();
373
+
374
+ let src_eid = 101;
375
+ let sender = BytesN::from_array(&env, &[1u8; 32]);
376
+ let nonce = 1;
377
+
378
+ let non_owner = Address::generate(&env);
379
+ env.mock_auths(&[MockAuth {
380
+ address: &non_owner,
381
+ invoke: &MockAuthInvoke {
382
+ contract: &counter.address,
383
+ fn_name: "skip_inbound_nonce",
384
+ args: (&src_eid, &sender, &nonce).into_val(&env),
385
+ sub_invokes: &[],
386
+ },
387
+ }]);
388
+
389
+ counter.skip_inbound_nonce(&src_eid, &sender, &nonce);
390
+ }
@@ -0,0 +1,21 @@
1
+ use soroban_sdk::U256;
2
+
3
+ pub trait U256Ext {
4
+ /// Converts U256 to i128 if the value fits.
5
+ /// Returns None if the value is too large to fit in an i128.
6
+ fn to_i128(&self) -> Option<i128>;
7
+ }
8
+
9
+ impl U256Ext for U256 {
10
+ fn to_i128(&self) -> Option<i128> {
11
+ // First try to convert to u128 (checks if high 128 bits are zero)
12
+ let u128_val = self.to_u128()?;
13
+
14
+ // Check if the u128 value fits within i128::MAX
15
+ if u128_val <= i128::MAX as u128 {
16
+ Some(u128_val as i128)
17
+ } else {
18
+ None
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,2 @@
1
+ #![no_std]
2
+ // This is an empty library crate that serves as a parent for message-lib packages
@@ -0,0 +1,21 @@
1
+ [package]
2
+ name = "oapp"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lib]
8
+ crate-type = ["rlib"]
9
+ doctest = false
10
+
11
+ [dependencies]
12
+ soroban-sdk = { workspace = true }
13
+ # workspace dependencies
14
+ utils = { workspace = true }
15
+ common-macros = { workspace = true }
16
+ endpoint-v2 = { workspace = true, features = ["library"] }
17
+ oapp-macros = { workspace = true }
18
+
19
+ [dev-dependencies]
20
+ soroban-sdk = { workspace = true, features = ["testutils"] }
21
+ utils = { workspace = true, features = ["testutils"] }
@@ -0,0 +1,9 @@
1
+ use common_macros::contract_error;
2
+
3
+ #[contract_error]
4
+ pub enum OAppError {
5
+ InvalidOptions = 20000,
6
+ NoPeer,
7
+ OnlyPeer,
8
+ ZROTokenUnavailable,
9
+ }
@@ -0,0 +1,10 @@
1
+ #![no_std]
2
+
3
+ pub mod errors;
4
+ pub mod oapp_core;
5
+ pub mod oapp_options_type3;
6
+ pub mod oapp_receiver;
7
+ pub mod oapp_sender;
8
+
9
+ #[cfg(test)]
10
+ mod tests;
@@ -0,0 +1,92 @@
1
+ use common_macros::{event, storage};
2
+ use endpoint_v2::LayerZeroEndpointV2Client;
3
+ use soroban_sdk::{Address, BytesN, Env};
4
+ use utils::{ownable::Ownable, ttl::DefaultTtlConfigProvider};
5
+
6
+ pub trait OAppCore: Ownable {
7
+ /// Retrieves the OApp version information.
8
+ ///
9
+ /// # Returns
10
+ /// A tuple containing:
11
+ /// - `sender_version`: The version of the OAppSender implementation
12
+ /// - `receiver_version`: The version of the OAppReceiver implementation
13
+ fn oapp_version(env: &Env) -> (u64, u64);
14
+
15
+ /// Retrieves the LayerZero endpoint associated with the OApp.
16
+ ///
17
+ /// # Returns
18
+ /// The LayerZero endpoint client
19
+ fn endpoint(env: &Env) -> Address;
20
+
21
+ /// Retrieves the peer (OApp) associated with a corresponding endpoint.
22
+ ///
23
+ /// # Arguments
24
+ /// * `eid` - The endpoint ID
25
+ ///
26
+ /// # Returns
27
+ /// The peer address (OApp instance) associated with the corresponding endpoint
28
+ fn peer(env: &Env, eid: u32) -> Option<BytesN<32>>;
29
+
30
+ /// Sets or removes the peer address (OApp instance) for a corresponding endpoint.
31
+ ///
32
+ /// # Arguments
33
+ /// * `eid` - The endpoint ID
34
+ /// * `peer` - The address of the peer to be associated with the corresponding endpoint, or None to remove the peer
35
+ fn set_peer(env: &Env, eid: u32, peer: &Option<BytesN<32>>);
36
+
37
+ /// Sets the delegate address for the OApp Core.
38
+ ///
39
+ /// # Arguments
40
+ /// * `delegate` - The address of the delegate to be set, or None to remove the delegate
41
+ fn set_delegate(env: &Env, delegate: &Option<Address>);
42
+ }
43
+
44
+ // =====================================================
45
+ // Implement overrides for the OAppCore trait
46
+ // =====================================================
47
+
48
+ #[storage(DefaultTtlConfigProvider)]
49
+ pub enum OAppCoreStorage {
50
+ #[instance(Address)]
51
+ Endpoint,
52
+
53
+ #[persistent(BytesN<32>)]
54
+ Peer { eid: u32 },
55
+ }
56
+
57
+ #[event]
58
+ pub struct PeerSet {
59
+ pub eid: u32,
60
+ pub peer: Option<BytesN<32>>,
61
+ }
62
+
63
+ pub trait OAppCoreOverrides {
64
+ fn __oapp_initialize(env: &Env, endpoint: &Address, delegate: &Option<Address>) {
65
+ OAppCoreStorage::set_endpoint(env, endpoint);
66
+ let endpoint_client = endpoint_v2::LayerZeroEndpointV2Client::new(env, endpoint);
67
+ endpoint_client.set_delegate(&env.current_contract_address(), delegate);
68
+ }
69
+
70
+ fn __oapp_version(_env: &Env) -> (u64, u64) {
71
+ (0, 0)
72
+ }
73
+
74
+ fn __endpoint(env: &Env) -> Address {
75
+ OAppCoreStorage::endpoint(env).unwrap()
76
+ }
77
+
78
+ fn __peer(env: &Env, eid: u32) -> Option<BytesN<32>> {
79
+ OAppCoreStorage::peer(env, eid)
80
+ }
81
+
82
+ fn __set_peer(env: &Env, eid: u32, peer: &Option<BytesN<32>>) {
83
+ OAppCoreStorage::set_or_remove_peer(env, eid, peer);
84
+ PeerSet { eid, peer: peer.clone() }.publish(env);
85
+ }
86
+
87
+ fn __set_delegate(env: &Env, delegate: &Option<Address>) {
88
+ let endpoint = Self::__endpoint(env);
89
+ let endpoint_client = LayerZeroEndpointV2Client::new(env, &endpoint);
90
+ endpoint_client.set_delegate(&env.current_contract_address(), delegate);
91
+ }
92
+ }
@@ -0,0 +1,89 @@
1
+ use crate::errors::OAppError;
2
+ use common_macros::{event, storage};
3
+ use soroban_sdk::{assert_with_error, contracttype, panic_with_error, Bytes, Env, Vec};
4
+ use utils::ttl::DefaultTtlConfigProvider;
5
+
6
+ // =====================================================
7
+ // Types and Traits
8
+ // =====================================================
9
+
10
+ pub const OPTION_TYPE3: u32 = 3;
11
+
12
+ #[contracttype]
13
+ #[derive(Clone, Debug, Eq, PartialEq)]
14
+ pub struct EnforcedOptionParam {
15
+ pub eid: u32,
16
+ pub msg_type: u32,
17
+ pub options: Bytes,
18
+ }
19
+
20
+ pub trait OAppOptionsType3 {
21
+ fn enforced_options(env: &Env, eid: u32, msg_type: u32) -> Bytes;
22
+
23
+ fn set_enforced_options(env: &Env, options: Vec<EnforcedOptionParam>);
24
+
25
+ fn combine_options(env: &Env, eid: u32, msg_type: u32, extra_options: &Bytes) -> Bytes;
26
+ }
27
+
28
+ // =====================================================
29
+ // Implement overrides for the OAppOptionsType3 trait
30
+ // =====================================================
31
+
32
+ #[storage(DefaultTtlConfigProvider)]
33
+ pub enum OAppOptionsType3Storage {
34
+ #[persistent(Bytes)]
35
+ #[default(Bytes::new(env))]
36
+ EnforcedOptions { eid: u32, msg_type: u32 },
37
+ }
38
+
39
+ #[event]
40
+ pub struct EnforcedOptionSet {
41
+ pub enforced_option_params: Vec<EnforcedOptionParam>,
42
+ }
43
+
44
+ pub trait OAppOptionsType3Overrides {
45
+ fn __enforced_options(env: &Env, eid: u32, msg_type: u32) -> Bytes {
46
+ OAppOptionsType3Storage::enforced_options(env, eid, msg_type)
47
+ }
48
+
49
+ fn __set_enforced_options(env: &Env, options: Vec<EnforcedOptionParam>) {
50
+ for option in &options {
51
+ assert_option_type3(env, &option.options);
52
+ OAppOptionsType3Storage::set_enforced_options(env, option.eid, option.msg_type, &option.options);
53
+ }
54
+ EnforcedOptionSet { enforced_option_params: options }.publish(env);
55
+ }
56
+
57
+ fn __combine_options(env: &Env, eid: u32, msg_type: u32, extra_options: &Bytes) -> Bytes {
58
+ let mut enforced_options = Self::__enforced_options(env, eid, msg_type);
59
+
60
+ if enforced_options.is_empty() {
61
+ return extra_options.clone();
62
+ }
63
+
64
+ if extra_options.is_empty() {
65
+ return enforced_options;
66
+ }
67
+
68
+ if extra_options.len() >= 2 {
69
+ assert_option_type3(env, extra_options);
70
+
71
+ enforced_options.append(&extra_options.slice(2..));
72
+ return enforced_options;
73
+ }
74
+
75
+ panic_with_error!(env, OAppError::InvalidOptions);
76
+ }
77
+ }
78
+
79
+ // =====================================================
80
+ // Internal Helpers
81
+ // =====================================================
82
+
83
+ pub fn assert_option_type3(env: &Env, options: &Bytes) {
84
+ let mut options_version_bytes = [0u8; 2];
85
+ options.slice(0..2).copy_into_slice(&mut options_version_bytes);
86
+ let options_version = u16::from_be_bytes(options_version_bytes);
87
+
88
+ assert_with_error!(env, options_version as u32 == OPTION_TYPE3, OAppError::InvalidOptions);
89
+ }