@layerzerolabs/protocol-stellar-v2 0.2.8 → 0.2.9

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 (239) hide show
  1. package/.turbo/turbo-build.log +443 -302
  2. package/.turbo/turbo-lint.log +118 -96
  3. package/.turbo/turbo-test.log +853 -731
  4. package/Cargo.lock +120 -37
  5. package/Cargo.toml +8 -5
  6. package/contracts/common-macros/src/contract_impl.rs +44 -0
  7. package/contracts/common-macros/src/lib.rs +86 -40
  8. package/contracts/common-macros/src/ownable.rs +24 -32
  9. package/contracts/common-macros/src/storage.rs +95 -120
  10. package/contracts/common-macros/src/tests/contract_impl.rs +289 -0
  11. package/contracts/common-macros/src/tests/mod.rs +9 -0
  12. package/contracts/common-macros/src/tests/ownable.rs +151 -0
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap +85 -0
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +30 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap +9 -0
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__storage__snapshot_generated_storage_code.snap +1072 -0
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +45 -0
  18. package/contracts/common-macros/src/tests/storage.rs +485 -0
  19. package/contracts/common-macros/src/tests/test_helpers.rs +93 -0
  20. package/contracts/common-macros/src/tests/ttl_configurable.rs +34 -0
  21. package/contracts/common-macros/src/ttl_configurable.rs +31 -14
  22. package/contracts/common-macros/src/utils.rs +27 -0
  23. package/contracts/endpoint-v2/ARCHITECTURE.md +4 -4
  24. package/contracts/endpoint-v2/src/endpoint_v2.rs +18 -15
  25. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +2 -3
  26. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +5 -3
  27. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +2 -2
  28. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
  29. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +4 -4
  30. package/contracts/endpoint-v2/src/lib.rs +6 -5
  31. package/contracts/endpoint-v2/src/message_lib_manager.rs +14 -6
  32. package/contracts/endpoint-v2/src/messaging_channel.rs +6 -2
  33. package/contracts/endpoint-v2/src/messaging_composer.rs +6 -2
  34. package/contracts/endpoint-v2/src/storage.rs +10 -7
  35. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +16 -16
  36. package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +46 -46
  37. package/contracts/endpoint-v2/src/tests/mock.rs +2 -2
  38. package/contracts/endpoint-v2/src/util.rs +8 -2
  39. package/contracts/message-libs/block-message-lib/Cargo.toml +1 -0
  40. package/contracts/message-libs/block-message-lib/src/lib.rs +5 -5
  41. package/contracts/message-libs/message-lib-common/src/errors.rs +8 -8
  42. package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +0 -1
  43. package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +3 -3
  44. package/contracts/message-libs/message-lib-common/src/lib.rs +0 -2
  45. package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +4 -6
  46. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +2 -2
  47. package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +11 -11
  48. package/contracts/message-libs/message-lib-common/src/worker_options.rs +10 -16
  49. package/contracts/message-libs/simple-message-lib/src/errors.rs +0 -4
  50. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +49 -34
  51. package/contracts/message-libs/simple-message-lib/src/storage.rs +3 -7
  52. package/contracts/message-libs/simple-message-lib/src/test.rs +3 -3
  53. package/contracts/message-libs/treasury/src/storage.rs +1 -2
  54. package/contracts/message-libs/treasury/src/tests/setup.rs +3 -2
  55. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +0 -13
  56. package/contracts/message-libs/treasury/src/treasury.rs +18 -21
  57. package/contracts/message-libs/uln-302/Cargo.toml +1 -0
  58. package/contracts/message-libs/uln-302/src/interfaces/mod.rs +4 -4
  59. package/contracts/message-libs/uln-302/src/interfaces/{receive.rs → receive_uln.rs} +3 -3
  60. package/contracts/message-libs/uln-302/src/interfaces/{send.rs → send_uln.rs} +8 -80
  61. package/contracts/message-libs/uln-302/src/lib.rs +5 -4
  62. package/contracts/message-libs/uln-302/src/{receive.rs → receive_uln.rs} +20 -12
  63. package/contracts/message-libs/uln-302/src/{send.rs → send_uln.rs} +19 -13
  64. package/contracts/message-libs/uln-302/src/storage.rs +1 -2
  65. package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +3 -2
  66. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +30 -30
  67. package/contracts/message-libs/uln-302/src/tests/setup.rs +12 -11
  68. package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +1 -1
  69. package/contracts/message-libs/uln-302/src/{config_validation.rs → types.rs} +79 -11
  70. package/contracts/message-libs/uln-302/src/uln302.rs +15 -10
  71. package/contracts/oapp-macros/Cargo.toml +2 -8
  72. package/contracts/oapp-macros/src/lib.rs +57 -311
  73. package/contracts/oapp-macros/src/oapp_core.rs +23 -32
  74. package/contracts/oapp-macros/src/oapp_full.rs +8 -2
  75. package/contracts/oapp-macros/src/oapp_options_type3.rs +21 -36
  76. package/contracts/oapp-macros/src/oapp_receiver.rs +38 -57
  77. package/contracts/oapp-macros/src/oapp_sender.rs +12 -14
  78. package/contracts/oapp-macros/src/util.rs +14 -10
  79. package/contracts/oapps/counter/Cargo.toml +2 -1
  80. package/contracts/oapps/counter/integration_tests/utils.rs +4 -4
  81. package/contracts/oapps/counter/src/codec.rs +8 -9
  82. package/contracts/oapps/counter/src/counter.rs +156 -147
  83. package/contracts/oapps/counter/src/storage.rs +1 -2
  84. package/contracts/oapps/counter/src/tests/test_codec.rs +5 -5
  85. package/contracts/oapps/counter/src/tests/test_counter.rs +11 -13
  86. package/contracts/oapps/oapp/Cargo.toml +1 -0
  87. package/contracts/oapps/oapp/src/errors.rs +1 -1
  88. package/contracts/oapps/oapp/src/lib.rs +3 -0
  89. package/contracts/oapps/oapp/src/macro_tests/mod.rs +1 -0
  90. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +312 -0
  91. package/contracts/oapps/oapp/src/oapp_core.rs +52 -53
  92. package/contracts/oapps/oapp/src/oapp_options_type3.rs +18 -28
  93. package/contracts/oapps/oapp/src/oapp_receiver.rs +82 -31
  94. package/contracts/oapps/oapp/src/oapp_sender.rs +55 -13
  95. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +16 -3
  96. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +33 -8
  97. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +6 -9
  98. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +28 -15
  99. package/contracts/oapps/oft/Cargo.toml +27 -0
  100. package/contracts/oapps/oft/integration-tests/mod.rs +3 -0
  101. package/contracts/oapps/oft/integration-tests/setup.rs +320 -0
  102. package/contracts/oapps/oft/integration-tests/test_with_sml.rs +155 -0
  103. package/contracts/oapps/oft/integration-tests/utils.rs +201 -0
  104. package/contracts/oapps/oft/src/codec/mod.rs +2 -0
  105. package/contracts/oapps/oft/src/codec/oft_compose_msg_codec.rs +55 -0
  106. package/contracts/oapps/oft/src/codec/oft_msg_codec.rs +62 -0
  107. package/contracts/oapps/oft/src/constants.rs +5 -0
  108. package/contracts/oapps/oft/src/errors.rs +8 -0
  109. package/contracts/oapps/oft/src/events.rs +19 -0
  110. package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +23 -0
  111. package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
  112. package/contracts/oapps/oft/src/lib.rs +22 -0
  113. package/contracts/oapps/oft/src/macro_tests/mod.rs +2 -0
  114. package/contracts/oapps/oft/src/macro_tests/test_all_default.rs +41 -0
  115. package/contracts/oapps/oft/src/macro_tests/test_override.rs +83 -0
  116. package/contracts/oapps/oft/src/oft.rs +320 -0
  117. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +50 -0
  118. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +50 -0
  119. package/contracts/oapps/oft/src/oft_types/mod.rs +10 -0
  120. package/contracts/oapps/oft/src/storage.rs +11 -0
  121. package/contracts/oapps/oft/src/tests/mod.rs +13 -0
  122. package/contracts/oapps/oft/src/tests/test_decimals.rs +89 -0
  123. package/contracts/oapps/oft/src/tests/test_lz_receive.rs +282 -0
  124. package/contracts/oapps/oft/src/tests/test_oft_compose_msg_codec.rs +68 -0
  125. package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +136 -0
  126. package/contracts/oapps/oft/src/tests/test_oft_version.rs +13 -0
  127. package/contracts/oapps/oft/src/tests/test_quote_oft.rs +159 -0
  128. package/contracts/oapps/oft/src/tests/test_quote_send.rs +195 -0
  129. package/contracts/oapps/oft/src/tests/test_resolve_address.rs +37 -0
  130. package/contracts/oapps/oft/src/tests/test_send.rs +915 -0
  131. package/contracts/oapps/oft/src/tests/test_token.rs +47 -0
  132. package/contracts/oapps/oft/src/tests/test_utils.rs +789 -0
  133. package/contracts/oapps/oft/src/types.rs +38 -0
  134. package/contracts/oapps/oft/src/utils.rs +67 -0
  135. package/contracts/oapps/oft-mint-burn/Cargo.toml +26 -0
  136. package/contracts/oapps/oft-mint-burn/src/lib.rs +3 -0
  137. package/contracts/oapps/oft-mint-burn/src/oft.rs +28 -0
  138. package/contracts/oapps/oft-mint-burn/src/tests/mod.rs +1 -0
  139. package/contracts/utils/src/buffer_reader.rs +8 -9
  140. package/contracts/utils/src/buffer_writer.rs +11 -5
  141. package/contracts/utils/src/errors.rs +5 -5
  142. package/contracts/utils/src/ownable.rs +14 -6
  143. package/contracts/utils/src/testing_utils.rs +11 -1
  144. package/contracts/utils/src/tests/buffer_reader.rs +491 -730
  145. package/contracts/utils/src/tests/buffer_writer.rs +336 -148
  146. package/contracts/utils/src/tests/bytes_ext.rs +125 -40
  147. package/contracts/utils/src/tests/mod.rs +3 -0
  148. package/contracts/utils/src/tests/ownable.rs +379 -27
  149. package/contracts/utils/src/tests/test_helper.rs +47 -0
  150. package/contracts/utils/src/tests/testing_utils.rs +555 -0
  151. package/contracts/utils/src/tests/ttl.rs +421 -0
  152. package/contracts/utils/src/ttl.rs +29 -89
  153. package/contracts/workers/dvn/Cargo.toml +31 -0
  154. package/contracts/workers/dvn/src/auth.rs +66 -0
  155. package/contracts/workers/dvn/src/dvn.rs +143 -0
  156. package/contracts/workers/dvn/src/errors.rs +21 -0
  157. package/contracts/workers/dvn/src/events.rs +19 -0
  158. package/contracts/workers/dvn/src/interfaces/dvn.rs +12 -0
  159. package/contracts/workers/dvn/src/interfaces/mod.rs +5 -0
  160. package/contracts/workers/dvn/src/interfaces/multisig.rs +15 -0
  161. package/contracts/workers/dvn/src/lib.rs +24 -0
  162. package/contracts/workers/dvn/src/multisig.rs +127 -0
  163. package/contracts/workers/dvn/src/storage.rs +35 -0
  164. package/contracts/workers/dvn/src/tests/auth.rs +237 -0
  165. package/contracts/workers/dvn/src/tests/dvn.rs +349 -0
  166. package/contracts/workers/dvn/src/tests/key_pair.rs +66 -0
  167. package/contracts/workers/dvn/src/tests/mod.rs +5 -0
  168. package/contracts/workers/dvn/src/tests/multisig/mod.rs +3 -0
  169. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +133 -0
  170. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +108 -0
  171. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +109 -0
  172. package/contracts/workers/dvn/src/tests/setup.rs +109 -0
  173. package/contracts/workers/dvn/src/types.rs +26 -0
  174. package/contracts/workers/dvn-fee-lib/Cargo.toml +24 -0
  175. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +113 -0
  176. package/contracts/workers/dvn-fee-lib/src/errors.rs +8 -0
  177. package/contracts/workers/dvn-fee-lib/src/lib.rs +17 -0
  178. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +282 -0
  179. package/contracts/workers/dvn-fee-lib/src/tests/mod.rs +1 -0
  180. package/contracts/workers/executor/Cargo.toml +10 -7
  181. package/contracts/workers/executor/src/errors.rs +8 -0
  182. package/contracts/workers/executor/src/events.rs +4 -7
  183. package/contracts/workers/executor/src/interfaces/executor.rs +72 -22
  184. package/contracts/workers/executor/src/interfaces/mod.rs +0 -2
  185. package/contracts/workers/executor/src/lib.rs +16 -7
  186. package/contracts/workers/executor/src/lz_executor.rs +308 -0
  187. package/contracts/workers/executor/src/storage.rs +24 -16
  188. package/contracts/workers/executor-fee-lib/Cargo.toml +22 -0
  189. package/contracts/workers/executor-fee-lib/src/errors.rs +15 -0
  190. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +215 -0
  191. package/contracts/workers/executor-fee-lib/src/executor_option.rs +203 -0
  192. package/contracts/workers/executor-fee-lib/src/lib.rs +7 -0
  193. package/contracts/workers/executor-helper/Cargo.toml +29 -0
  194. package/contracts/workers/executor-helper/src/executor_helper.rs +161 -0
  195. package/contracts/workers/executor-helper/src/lib.rs +11 -0
  196. package/contracts/workers/{worker-common → worker}/Cargo.toml +1 -4
  197. package/contracts/workers/worker/src/errors.rs +24 -0
  198. package/contracts/workers/worker/src/events.rs +62 -0
  199. package/contracts/workers/worker/src/interfaces/dvn_fee_lib.rs +75 -0
  200. package/contracts/workers/worker/src/interfaces/executor_fee_lib.rs +84 -0
  201. package/contracts/workers/{worker-common → worker}/src/interfaces/mod.rs +2 -2
  202. package/contracts/workers/worker/src/interfaces/price_feed.rs +85 -0
  203. package/contracts/workers/worker/src/lib.rs +14 -0
  204. package/contracts/workers/worker/src/storage.rs +63 -0
  205. package/contracts/workers/worker/src/worker.rs +459 -0
  206. package/package.json +3 -3
  207. package/sdk/dist/generated/bml.d.ts +88 -17
  208. package/sdk/dist/generated/bml.js +62 -16
  209. package/sdk/dist/generated/counter.d.ts +281 -102
  210. package/sdk/dist/generated/counter.js +93 -41
  211. package/sdk/dist/generated/endpoint.d.ts +128 -105
  212. package/sdk/dist/generated/endpoint.js +47 -45
  213. package/sdk/dist/generated/sml.d.ts +212 -69
  214. package/sdk/dist/generated/sml.js +103 -53
  215. package/sdk/dist/generated/uln302.d.ts +270 -173
  216. package/sdk/dist/generated/uln302.js +112 -64
  217. package/sdk/package.json +11 -11
  218. package/sdk/test/index.test.ts +147 -42
  219. package/sdk/test/suites/constants.ts +7 -3
  220. package/sdk/test/suites/deploy.ts +65 -42
  221. package/sdk/test/suites/localnet.ts +2 -2
  222. package/sdk/test/suites/scan.ts +28 -25
  223. package/sdk/test/utils.ts +199 -0
  224. package/sdk/tsconfig.json +93 -95
  225. package/tools/ts-bindings-gen/src/main.rs +2 -0
  226. package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +0 -310
  227. package/contracts/common-macros/src/tests.rs +0 -287
  228. package/contracts/oapp-macros/tests/test_macros.rs +0 -522
  229. package/contracts/workers/executor/src/executor.rs +0 -347
  230. package/contracts/workers/executor/src/interfaces/types.rs +0 -51
  231. package/contracts/workers/worker-common/src/constants.rs +0 -17
  232. package/contracts/workers/worker-common/src/errors.rs +0 -6
  233. package/contracts/workers/worker-common/src/events.rs +0 -34
  234. package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +0 -35
  235. package/contracts/workers/worker-common/src/interfaces/price_feed.rs +0 -40
  236. package/contracts/workers/worker-common/src/interfaces/worker.rs +0 -60
  237. package/contracts/workers/worker-common/src/lib.rs +0 -19
  238. package/contracts/workers/worker-common/src/storage.rs +0 -32
  239. package/contracts/workers/worker-common/src/worker_common.rs +0 -166
@@ -0,0 +1,50 @@
1
+ //! LockUnlock type implementation for OFT.
2
+ //!
3
+ //! This OFT type locks tokens in the contract on debit (send) and unlocks
4
+ //! tokens from the contract on credit (receive).
5
+ //! Used for OFT adapters that wrap existing tokens.
6
+
7
+ use soroban_sdk::{token::TokenClient, Address, Env};
8
+
9
+ use crate::oft::OFT;
10
+ use crate::types::OFTReceipt;
11
+
12
+ /// Debit tokens using LockUnlock OFT type (locks tokens in contract).
13
+ ///
14
+ /// # Parameters
15
+ /// * `env` - The Soroban environment
16
+ /// * `sender` - Address of the token sender
17
+ /// * `amount_ld` - Amount to debit in local decimals
18
+ /// * `min_amount_ld` - Minimum amount that must be received (for slippage protection)
19
+ /// * `dst_eid` - Destination endpoint ID
20
+ ///
21
+ /// # Returns
22
+ /// `OFTReceipt` containing the amount sent and amount received
23
+ pub fn debit<T: OFT>(env: &Env, sender: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> OFTReceipt {
24
+ let receipt: OFTReceipt = T::__debit_view(env, amount_ld, min_amount_ld, dst_eid);
25
+ TokenClient::new(env, &T::token(env)).transfer(sender, env.current_contract_address(), &receipt.amount_sent_ld);
26
+ receipt
27
+ }
28
+
29
+ /// Credit tokens using LockUnlock OFT type (unlocks tokens from contract).
30
+ ///
31
+ /// # Parameters
32
+ /// * `env` - The Soroban environment
33
+ /// * `to` - Address of the token recipient
34
+ /// * `amount_ld` - Amount to credit in local decimals
35
+ /// * `_src_eid` - Source endpoint ID (unused)
36
+ ///
37
+ /// # Returns
38
+ /// The amount credited
39
+ pub fn credit<T: OFT>(env: &Env, to: &Address, amount_ld: i128, _src_eid: u32) -> i128 {
40
+ TokenClient::new(env, &T::token(env)).transfer(&env.current_contract_address(), to, &amount_ld);
41
+ amount_ld
42
+ }
43
+
44
+ /// Returns whether approval is required for LockUnlock OFT type.
45
+ ///
46
+ /// # Returns
47
+ /// Always `false` - approval not needed for transfer operations
48
+ pub fn approval_required() -> bool {
49
+ false
50
+ }
@@ -0,0 +1,50 @@
1
+ //! MintBurn type implementation for OFT.
2
+ //!
3
+ //! This OFT type burns tokens on debit (send) and mints tokens on credit (receive).
4
+ //! Used when the OFT contract has mint/burn authority over the token.
5
+
6
+ use soroban_sdk::{Address, Env};
7
+
8
+ use crate::interfaces::MintBurnTokenClient;
9
+ use crate::oft::OFT;
10
+ use crate::types::OFTReceipt;
11
+
12
+ /// Debit tokens using MintBurn OFT type (burns tokens from sender).
13
+ ///
14
+ /// # Parameters
15
+ /// * `env` - The Soroban environment
16
+ /// * `sender` - Address of the token sender
17
+ /// * `amount_ld` - Amount to debit in local decimals
18
+ /// * `min_amount_ld` - Minimum amount that must be received (for slippage protection)
19
+ /// * `dst_eid` - Destination endpoint ID
20
+ ///
21
+ /// # Returns
22
+ /// `OFTReceipt` containing the amount sent and amount received
23
+ pub fn debit<T: OFT>(env: &Env, sender: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> OFTReceipt {
24
+ let receipt = T::__debit_view(env, amount_ld, min_amount_ld, dst_eid);
25
+ MintBurnTokenClient::new(env, &T::token(env)).burn(sender, &receipt.amount_sent_ld);
26
+ receipt
27
+ }
28
+
29
+ /// Credit tokens using MintBurn OFT type (mints tokens to recipient).
30
+ ///
31
+ /// # Parameters
32
+ /// * `env` - The Soroban environment
33
+ /// * `to` - Address of the token recipient
34
+ /// * `amount_ld` - Amount to credit in local decimals
35
+ /// * `_src_eid` - Source endpoint ID (unused)
36
+ ///
37
+ /// # Returns
38
+ /// The amount credited
39
+ pub fn credit<T: OFT>(env: &Env, to: &Address, amount_ld: i128, _src_eid: u32) -> i128 {
40
+ MintBurnTokenClient::new(env, &T::token(env)).mint(to, &amount_ld);
41
+ amount_ld
42
+ }
43
+
44
+ /// Returns whether approval is required for MintBurn OFT type.
45
+ ///
46
+ /// # Returns
47
+ /// Always `false` - approval not needed for mint/burn operations.
48
+ pub fn approval_required() -> bool {
49
+ false
50
+ }
@@ -0,0 +1,10 @@
1
+ //! OFT types implementations.
2
+ //!
3
+ //! This module provides reference implementations for the two main OFT types:
4
+ //!
5
+ //! - **MintBurn**: Burns tokens on send, mints on receive. Approval not required.
6
+ //! - **LockUnlock**: Locks tokens on send, unlocks on receive. Approval not required.
7
+ //!
8
+
9
+ pub mod lock_unlock;
10
+ pub mod mint_burn;
@@ -0,0 +1,11 @@
1
+ use common_macros::storage;
2
+ use soroban_sdk::Address;
3
+
4
+ #[storage]
5
+ pub enum OFTStorage {
6
+ #[instance(i128)]
7
+ DecimalConversionRate,
8
+
9
+ #[instance(Address)]
10
+ Token,
11
+ }
@@ -0,0 +1,13 @@
1
+ pub mod test_utils;
2
+
3
+ pub mod test_oft_compose_msg_codec;
4
+ pub mod test_oft_msg_codec;
5
+
6
+ pub mod test_decimals;
7
+ pub mod test_lz_receive;
8
+ pub mod test_oft_version;
9
+ pub mod test_quote_oft;
10
+ pub mod test_quote_send;
11
+ pub mod test_resolve_address;
12
+ pub mod test_send;
13
+ pub mod test_token;
@@ -0,0 +1,89 @@
1
+ use super::test_utils::OFTTestSetup;
2
+ use crate::{
3
+ tests::test_utils::OFTTestSetupBuilder,
4
+ utils::{to_ld, to_sd},
5
+ };
6
+ use soroban_sdk::Env;
7
+
8
+ #[test]
9
+ fn test_decimal_conversion_rate() {
10
+ let env = Env::default();
11
+ let setup = OFTTestSetup::new(&env);
12
+
13
+ // SAC has 7 decimals, shared decimals is 6
14
+ // conversion_rate = 10^(7-6) = 10
15
+ let rate = setup.oft.decimal_conversion_rate();
16
+ assert_eq!(rate, 10_i128.pow(setup.token_decimals - setup.shared_decimals));
17
+ }
18
+
19
+ #[test]
20
+ #[should_panic(expected = "Error(Contract, #2100)")] // InvalidLocalDecimals
21
+ fn test_invalid_local_decimals() {
22
+ let env = Env::default();
23
+ OFTTestSetupBuilder::new(&env).with_token_decimals(5).with_shared_decimals(6).build();
24
+ }
25
+
26
+ #[test]
27
+ #[should_panic]
28
+ fn test_to_ld_overflow() {
29
+ // 10^38 * 10 > i128::MAX - should overflow
30
+ let conversion_rate = 10_i128.pow(38);
31
+ let amount_sd = 10u64;
32
+
33
+ to_ld(amount_sd, conversion_rate);
34
+ }
35
+
36
+ #[test]
37
+ #[should_panic(expected = "Error(Contract, #2101)")] // Overflow
38
+ fn test_to_sd_overflow() {
39
+ let env = Env::default();
40
+
41
+ // u64::MAX + 1 exceeds u64 range - should overflow
42
+ let conversion_rate = 1i128;
43
+ let amount_ld = u64::MAX as i128 + 1;
44
+
45
+ to_sd(&env, amount_ld, conversion_rate);
46
+ }
47
+
48
+ // ==================== Positive Conversion Tests ====================
49
+
50
+ #[test]
51
+ fn test_to_ld_basic() {
52
+ // Conversion rate = 10 (7 decimals - 6 shared = 1 decimal difference)
53
+ let conversion_rate = 10i128;
54
+
55
+ assert_eq!(to_ld(0, conversion_rate), 0);
56
+ assert_eq!(to_ld(1, conversion_rate), 10);
57
+ assert_eq!(to_ld(100, conversion_rate), 1_000);
58
+ assert_eq!(to_ld(1_000_000, conversion_rate), 10_000_000);
59
+ }
60
+
61
+ #[test]
62
+ fn test_to_sd_basic() {
63
+ let env = Env::default();
64
+
65
+ // Conversion rate = 10 (7 decimals - 6 shared = 1 decimal difference)
66
+ let conversion_rate = 10i128;
67
+
68
+ assert_eq!(to_sd(&env, 0, conversion_rate), 0);
69
+ assert_eq!(to_sd(&env, 10, conversion_rate), 1);
70
+ assert_eq!(to_sd(&env, 1_000, conversion_rate), 100);
71
+ assert_eq!(to_sd(&env, 10_000_000, conversion_rate), 1_000_000);
72
+ }
73
+
74
+ #[test]
75
+ fn test_to_sd_truncates_dust() {
76
+ let env = Env::default();
77
+
78
+ // Conversion rate = 10
79
+ let conversion_rate = 10i128;
80
+
81
+ // 15 LD → 1 SD (5 is dust, truncated via division)
82
+ assert_eq!(to_sd(&env, 15, conversion_rate), 1);
83
+
84
+ // 19 LD → 1 SD (9 is dust, truncated)
85
+ assert_eq!(to_sd(&env, 19, conversion_rate), 1);
86
+
87
+ // 20 LD → 2 SD (exact)
88
+ assert_eq!(to_sd(&env, 20, conversion_rate), 2);
89
+ }
@@ -0,0 +1,282 @@
1
+ use super::test_utils::OFTTestSetup;
2
+ use crate::{
3
+ events::OFTReceived,
4
+ tests::test_utils::{
5
+ create_origin, create_recipient_address, encode_oft_message, encode_oft_message_with_compose,
6
+ generate_g_address, OFTTestSetupBuilder,
7
+ },
8
+ utils::address_to_bytes32,
9
+ };
10
+ use endpoint_v2::LayerZeroReceiverClient;
11
+ use soroban_sdk::{testutils::Address as _, Address, Bytes, BytesN, Env};
12
+ use utils::testing_utils::assert_event;
13
+
14
+ // Helper function to reduce code duplication for lz_receive tests
15
+ fn run_lz_receive_test(setup: &OFTTestSetup, recipient: &Address, amount_sd: u64) {
16
+ let env = setup.env;
17
+ let executor = Address::generate(env);
18
+
19
+ let src_eid = 100u32;
20
+ let peer = BytesN::from_array(env, &[2u8; 32]);
21
+ setup.set_peer(src_eid, &peer);
22
+
23
+ // Check initial balance
24
+ let initial_balance = setup.token_client.balance(recipient);
25
+ let initial_oft_balance =
26
+ if setup.is_lock_unlock() { Some(setup.token_client.balance(&setup.oft.address)) } else { None };
27
+
28
+ // Create OFT message
29
+ let recipient_bytes32 = address_to_bytes32(recipient);
30
+ let message = encode_oft_message(env, &recipient_bytes32, amount_sd);
31
+
32
+ let guid = BytesN::from_array(env, &[1u8; 32]);
33
+ let origin = create_origin(src_eid, &peer, 1);
34
+ let extra_data = Bytes::new(env);
35
+
36
+ // Verify recipient received tokens
37
+ let conversion_rate = setup.oft.decimal_conversion_rate();
38
+ let expected_amount_ld = (amount_sd as i128) * conversion_rate;
39
+ setup.lz_receive(&executor, &origin, &guid, &message, &extra_data, 0);
40
+ assert_event(
41
+ env,
42
+ &setup.oft.address,
43
+ OFTReceived { guid: guid.clone(), src_eid, to: recipient.clone(), amount_received_ld: expected_amount_ld },
44
+ );
45
+ if setup.issuer == *recipient {
46
+ assert_eq!(setup.token_client.balance(recipient), i64::MAX as i128);
47
+ } else {
48
+ assert_eq!(setup.token_client.balance(recipient), initial_balance + expected_amount_ld);
49
+ }
50
+
51
+ // For LockUnlock strategy, verify OFT contract balance decreased
52
+ if let Some(initial_oft) = initial_oft_balance {
53
+ assert_eq!(setup.token_client.balance(&setup.oft.address), initial_oft - expected_amount_ld);
54
+ }
55
+ }
56
+
57
+ // ==================== MintBurn Strategy Tests ====================
58
+
59
+ #[test]
60
+ fn test_mint_burn_sac_lz_receive_to_c_address() {
61
+ let env = Env::default();
62
+ let recipient = create_recipient_address(&env);
63
+ let setup = OFTTestSetupBuilder::new(&env).with_sac().build();
64
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
65
+ }
66
+
67
+ #[test]
68
+ fn test_mint_burn_contract_token_lz_receive_to_c_address() {
69
+ let env = Env::default();
70
+ let recipient = create_recipient_address(&env);
71
+ let setup = OFTTestSetup::new(&env);
72
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
73
+ }
74
+
75
+ #[test]
76
+ #[should_panic(expected = "HostError: Error(Contract, #13)")] // trustline entry is missing for account
77
+ fn test_mint_burn_sac_lz_receive_to_g_address_with_no_trustline() {
78
+ let env = Env::default();
79
+ let recipient = generate_g_address(&env);
80
+ let setup = OFTTestSetupBuilder::new(&env).with_sac().build();
81
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
82
+ }
83
+
84
+ #[test]
85
+ #[should_panic(expected = "HostError: Error(Contract, #2)")] // operation invalid on issuer
86
+ fn test_mint_burn_sac_lz_receive_to_issuer() {
87
+ let env = Env::default();
88
+ let setup = OFTTestSetupBuilder::new(&env).with_sac().build();
89
+ run_lz_receive_test(&setup, &setup.issuer, 1_000_000u64);
90
+ }
91
+
92
+ #[test]
93
+ fn test_mint_burn_contract_token_lz_receive_to_g_address() {
94
+ let env = Env::default();
95
+ let recipient = generate_g_address(&env);
96
+ let setup = OFTTestSetup::new(&env);
97
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
98
+ }
99
+
100
+ #[test]
101
+ fn test_mint_burn_lz_receive_with_compose() {
102
+ let env = Env::default();
103
+ let setup = OFTTestSetup::new(&env);
104
+
105
+ let executor = Address::generate(&env);
106
+ let recipient = create_recipient_address(&env);
107
+ let sender_on_src = Address::generate(&env);
108
+
109
+ let src_eid = 100u32;
110
+ let peer = BytesN::from_array(&env, &[2u8; 32]);
111
+ setup.set_peer(src_eid, &peer);
112
+
113
+ // Create OFT message with compose
114
+ let recipient_bytes32 = address_to_bytes32(&recipient);
115
+ let compose_from = address_to_bytes32(&sender_on_src);
116
+ let compose_msg = Bytes::from_array(&env, b"test compose payload");
117
+ let amount_sd = 1000000u64;
118
+ let message = encode_oft_message_with_compose(&env, &recipient_bytes32, amount_sd, &compose_from, &compose_msg);
119
+
120
+ let guid = BytesN::from_array(&env, &[1u8; 32]);
121
+ let origin = create_origin(src_eid, &peer, 1);
122
+ let extra_data = Bytes::new(&env);
123
+
124
+ // Verify compose not called yet
125
+ assert!(!setup.endpoint_client.was_composed());
126
+
127
+ // Execute lz_receive
128
+ setup.lz_receive(&executor, &origin, &guid, &message, &extra_data, 0);
129
+
130
+ // Verify tokens were credited
131
+ let conversion_rate = setup.oft.decimal_conversion_rate();
132
+ let expected_amount_ld = (amount_sd as i128) * conversion_rate;
133
+ assert_eq!(setup.token_client.balance(&recipient), expected_amount_ld);
134
+
135
+ // Verify compose was called
136
+ assert!(setup.endpoint_client.was_composed());
137
+
138
+ // Verify compose recipient
139
+ let compose_to = setup.endpoint_client.get_compose_to().unwrap();
140
+ assert_eq!(compose_to, recipient);
141
+ }
142
+
143
+ #[test]
144
+ fn test_mint_burn_lz_receive_zero_amount() {
145
+ let env = Env::default();
146
+ let recipient = create_recipient_address(&env);
147
+ let setup = OFTTestSetup::new(&env);
148
+ run_lz_receive_test(&setup, &recipient, 0u64);
149
+ }
150
+
151
+ // ==================== Lock/Unlock Strategy Tests ====================
152
+
153
+ #[test]
154
+ fn test_lock_unlock_sac_lz_receive_to_c_address() {
155
+ let env = Env::default();
156
+ let recipient = create_recipient_address(&env);
157
+ let setup = OFTTestSetupBuilder::new(&env).lock_unlock().with_sac().build();
158
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
159
+ }
160
+
161
+ #[test]
162
+ fn test_lock_unlock_contract_token_lz_receive_to_c_address() {
163
+ let env = Env::default();
164
+ let recipient = create_recipient_address(&env);
165
+ let setup = OFTTestSetupBuilder::new(&env).lock_unlock().build();
166
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
167
+ }
168
+
169
+ #[test]
170
+ #[should_panic(expected = "HostError: Error(Contract, #13)")] // trustline entry is missing for account
171
+ fn test_lock_unlock_sac_lz_receive_to_g_address_with_no_trustline() {
172
+ let env = Env::default();
173
+ let recipient = generate_g_address(&env);
174
+ let setup = OFTTestSetupBuilder::new(&env).lock_unlock().with_sac().build();
175
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
176
+ }
177
+
178
+ #[test]
179
+ fn test_lock_unlock_sac_lz_receive_to_issuer() {
180
+ let env = Env::default();
181
+ let setup = OFTTestSetupBuilder::new(&env).lock_unlock().with_sac().build();
182
+ run_lz_receive_test(&setup, &setup.issuer, 1_000_000u64);
183
+ }
184
+
185
+ #[test]
186
+ fn test_lock_unlock_contract_token_lz_receive_to_g_address() {
187
+ let env = Env::default();
188
+ let recipient = generate_g_address(&env);
189
+ let setup = OFTTestSetupBuilder::new(&env).lock_unlock().build();
190
+ run_lz_receive_test(&setup, &recipient, 1_000_000u64);
191
+ }
192
+
193
+ #[test]
194
+ fn test_lock_unlock_lz_receive_with_compose() {
195
+ let env = Env::default();
196
+ let setup = OFTTestSetupBuilder::new(&env).lock_unlock().build();
197
+
198
+ let executor = Address::generate(&env);
199
+ let recipient = create_recipient_address(&env);
200
+ let sender_on_src = Address::generate(&env);
201
+
202
+ let src_eid = 100u32;
203
+ let peer = BytesN::from_array(&env, &[2u8; 32]);
204
+ setup.set_peer(src_eid, &peer);
205
+
206
+ // Create OFT message with compose
207
+ let recipient_bytes32 = address_to_bytes32(&recipient);
208
+ let compose_from = address_to_bytes32(&sender_on_src);
209
+ let compose_msg = Bytes::from_array(&env, b"test compose payload");
210
+ let amount_sd = 1000000u64;
211
+ let message = encode_oft_message_with_compose(&env, &recipient_bytes32, amount_sd, &compose_from, &compose_msg);
212
+
213
+ let guid = BytesN::from_array(&env, &[1u8; 32]);
214
+ let origin = create_origin(src_eid, &peer, 1);
215
+ let extra_data = Bytes::new(&env);
216
+
217
+ // Verify compose not called yet
218
+ assert!(!setup.endpoint_client.was_composed());
219
+
220
+ // Execute lz_receive
221
+ setup.lz_receive(&executor, &origin, &guid, &message, &extra_data, 0);
222
+
223
+ // Verify tokens were credited
224
+ let conversion_rate = setup.oft.decimal_conversion_rate();
225
+ let expected_amount_ld = (amount_sd as i128) * conversion_rate;
226
+ assert_eq!(setup.token_client.balance(&recipient), expected_amount_ld);
227
+
228
+ // Verify compose was called
229
+ assert!(setup.endpoint_client.was_composed());
230
+
231
+ // Verify compose recipient
232
+ let compose_to = setup.endpoint_client.get_compose_to().unwrap();
233
+ assert_eq!(compose_to, recipient);
234
+ }
235
+
236
+ #[test]
237
+ fn test_lock_unlock_lz_receive_zero_amount() {
238
+ let env = Env::default();
239
+ let recipient = create_recipient_address(&env);
240
+ let setup = OFTTestSetupBuilder::new(&env).lock_unlock().build();
241
+ run_lz_receive_test(&setup, &recipient, 0u64);
242
+ }
243
+
244
+ // ==================== Authorizations Tests ====================
245
+
246
+ #[test]
247
+ #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
248
+ fn test_lz_receive_without_giving_authorization() {
249
+ let env = Env::default();
250
+ let setup = OFTTestSetup::new(&env);
251
+
252
+ let executor = Address::generate(&env);
253
+ let recipient = create_recipient_address(&env);
254
+
255
+ // Set peer
256
+ let src_eid = 100u32;
257
+ let peer = BytesN::from_array(&env, &[2u8; 32]);
258
+ setup.set_peer(src_eid, &peer);
259
+
260
+ // Check initial balance
261
+ assert_eq!(setup.token_client.balance(&recipient), 0);
262
+
263
+ // Create OFT message
264
+ let recipient_bytes32 = address_to_bytes32(&recipient);
265
+ let amount_sd = 1000000u64; // 1 token in shared decimals
266
+ let message = encode_oft_message(&env, &recipient_bytes32, amount_sd);
267
+
268
+ // Create origin
269
+ let guid = BytesN::from_array(&env, &[1u8; 32]);
270
+ let origin = create_origin(src_eid, &peer, 1);
271
+ let extra_data = Bytes::new(&env);
272
+
273
+ // Execute lz_receive
274
+ LayerZeroReceiverClient::new(setup.env, &setup.oft.address).lz_receive(
275
+ &executor,
276
+ &origin,
277
+ &guid,
278
+ &message,
279
+ &extra_data,
280
+ &0i128,
281
+ );
282
+ }
@@ -0,0 +1,68 @@
1
+ use crate::codec::oft_compose_msg_codec::OFTComposeMsg;
2
+ use soroban_sdk::{Bytes, BytesN, Env};
3
+
4
+ #[test]
5
+ fn test_encode_and_decode_basic() {
6
+ let env = Env::default();
7
+ let nonce = 12345u64;
8
+ let src_eid = 101u32;
9
+ let amount_ld = 1_000_000_000i128; // 1 token with 9 decimals
10
+ let compose_from = BytesN::from_array(&env, &[0x42u8; 32]);
11
+ let compose_msg = Bytes::from_array(&env, b"test compose message");
12
+
13
+ let msg = OFTComposeMsg {
14
+ nonce,
15
+ src_eid,
16
+ amount_ld,
17
+ compose_from: compose_from.clone(),
18
+ compose_msg: compose_msg.clone(),
19
+ };
20
+
21
+ let encoded = msg.encode(&env);
22
+ let decoded = OFTComposeMsg::decode(&encoded);
23
+
24
+ assert_eq!(decoded.nonce, nonce);
25
+ assert_eq!(decoded.src_eid, src_eid);
26
+ assert_eq!(decoded.amount_ld, amount_ld);
27
+ assert_eq!(decoded.compose_from, compose_from);
28
+ assert_eq!(decoded.compose_msg, compose_msg);
29
+ }
30
+
31
+ #[test]
32
+ fn test_encode_with_empty_compose_msg() {
33
+ let env = Env::default();
34
+ let nonce = 123u64;
35
+ let src_eid = 1u32;
36
+ let amount_ld = 1_000_000i128;
37
+ let compose_from = BytesN::from_array(&env, &[0x11u8; 32]);
38
+ let compose_msg = Bytes::new(&env); // Empty
39
+
40
+ let msg = OFTComposeMsg { nonce, src_eid, amount_ld, compose_from: compose_from.clone(), compose_msg };
41
+
42
+ let encoded = msg.encode(&env);
43
+ let decoded = OFTComposeMsg::decode(&encoded);
44
+
45
+ assert_eq!(decoded.nonce, nonce);
46
+ assert_eq!(decoded.src_eid, src_eid);
47
+ assert_eq!(decoded.amount_ld, amount_ld);
48
+ assert_eq!(decoded.compose_from, compose_from);
49
+ assert_eq!(decoded.compose_msg.len(), 0);
50
+ }
51
+
52
+ #[test]
53
+ #[should_panic]
54
+ fn test_decode_panic_on_empty_data() {
55
+ let env = Env::default();
56
+ let data = Bytes::new(&env);
57
+ OFTComposeMsg::decode(&data);
58
+ }
59
+
60
+ #[test]
61
+ #[should_panic]
62
+ fn test_decode_panic_on_insufficient_data() {
63
+ let env = Env::default();
64
+ let mut data = Bytes::new(&env);
65
+ // Only 30 bytes - not enough for nonce(8) + src_eid(4) + amount_ld(16) + compose_from(32) = 60 bytes minimum
66
+ data.extend_from_array(&[0u8; 30]);
67
+ OFTComposeMsg::decode(&data);
68
+ }