@layerzerolabs/protocol-stellar-v2 0.2.19 → 0.2.21

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 (249) hide show
  1. package/.turbo/turbo-build.log +795 -791
  2. package/.turbo/turbo-lint.log +325 -155
  3. package/.turbo/turbo-test.log +1398 -1277
  4. package/Cargo.lock +122 -111
  5. package/Cargo.toml +32 -16
  6. package/contracts/common-macros/Cargo.toml +7 -7
  7. package/contracts/common-macros/src/auth.rs +18 -37
  8. package/contracts/common-macros/src/contract_ttl.rs +18 -7
  9. package/contracts/common-macros/src/lib.rs +31 -14
  10. package/contracts/common-macros/src/lz_contract.rs +38 -7
  11. package/contracts/common-macros/src/storage.rs +251 -292
  12. package/contracts/common-macros/src/tests/contract_ttl.rs +1 -1
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +6 -12
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +12 -17
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +2 -1
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +2 -7
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +20 -14
  18. package/contracts/common-macros/src/tests/upgradeable.rs +26 -4
  19. package/contracts/common-macros/src/ttl_configurable.rs +2 -10
  20. package/contracts/common-macros/src/ttl_extendable.rs +2 -10
  21. package/contracts/common-macros/src/upgradeable.rs +61 -26
  22. package/contracts/common-macros/src/utils.rs +0 -9
  23. package/contracts/endpoint-v2/src/lib.rs +3 -2
  24. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +2 -2
  25. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +3 -3
  26. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +4 -4
  27. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +17 -5
  28. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  29. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +2 -2
  30. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +2 -2
  31. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +6 -6
  32. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +67 -37
  33. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +5 -5
  34. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +44 -54
  35. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +7 -7
  36. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +8 -8
  37. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +3 -3
  38. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +4 -4
  39. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +3 -3
  40. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +2 -2
  41. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +3 -3
  42. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +2 -2
  43. package/contracts/layerzero-views/Cargo.toml +0 -1
  44. package/contracts/layerzero-views/src/layerzero_view.rs +1 -13
  45. package/contracts/macro-integration-tests/Cargo.toml +5 -15
  46. package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +48 -0
  47. package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +170 -0
  48. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +154 -0
  49. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +338 -0
  50. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +435 -0
  51. package/contracts/macro-integration-tests/tests/runtime.rs +1 -0
  52. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.rs +8 -0
  53. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -0
  54. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +8 -0
  55. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +71 -0
  56. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.rs +10 -0
  57. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +5 -0
  58. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.rs +8 -0
  59. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -0
  60. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.rs +8 -0
  61. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -0
  62. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +38 -0
  63. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +96 -0
  64. package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +64 -0
  65. package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +46 -0
  66. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +8 -0
  67. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +1 -1
  68. package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +1 -1
  69. package/contracts/macro-integration-tests/tests/ui_oapp.rs +11 -0
  70. package/contracts/message-libs/message-lib-common/Cargo.toml +0 -1
  71. package/contracts/message-libs/message-lib-common/src/errors.rs +1 -1
  72. package/contracts/message-libs/treasury/Cargo.toml +0 -2
  73. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +2 -2
  74. package/contracts/message-libs/uln-302/src/events.rs +4 -0
  75. package/contracts/message-libs/uln-302/src/send_uln.rs +22 -6
  76. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +2 -2
  77. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +2 -2
  78. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +2 -2
  79. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +2 -2
  80. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +2 -2
  81. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +21 -67
  82. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +2 -2
  83. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +2 -2
  84. package/contracts/oapps/counter/Cargo.toml +5 -6
  85. package/contracts/oapps/counter/integration_tests/setup_uln.rs +1 -1
  86. package/contracts/oapps/counter/integration_tests/utils.rs +19 -12
  87. package/contracts/oapps/oapp/src/errors.rs +1 -1
  88. package/contracts/oapps/oapp/src/interfaces/mod.rs +3 -0
  89. package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +47 -0
  90. package/contracts/oapps/oapp/src/lib.rs +1 -0
  91. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +4 -4
  92. package/contracts/oapps/oapp/src/oapp_core.rs +5 -5
  93. package/contracts/oapps/oapp/src/oapp_options_type3.rs +12 -4
  94. package/contracts/oapps/oapp/src/oapp_receiver.rs +14 -9
  95. package/contracts/oapps/oapp/src/tests/mod.rs +4 -4
  96. package/contracts/oapps/oapp/src/tests/oapp_core.rs +223 -0
  97. package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +240 -0
  98. package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +381 -0
  99. package/contracts/oapps/oapp/src/tests/oapp_sender.rs +569 -0
  100. package/contracts/oapps/oapp-macros/Cargo.toml +8 -4
  101. package/contracts/oapps/oapp-macros/src/generators.rs +9 -34
  102. package/contracts/oapps/oapp-macros/src/lib.rs +3 -0
  103. package/contracts/oapps/oapp-macros/src/tests/mod.rs +2 -0
  104. package/contracts/oapps/oapp-macros/src/tests/oapp.rs +88 -0
  105. package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +86 -0
  106. package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +103 -0
  107. package/contracts/oapps/oft/integration-tests/utils.rs +28 -8
  108. package/contracts/oapps/oft/src/extensions/oft_fee.rs +153 -75
  109. package/contracts/oapps/oft/src/extensions/pausable.rs +61 -12
  110. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +198 -134
  111. package/contracts/oapps/oft/src/oft.rs +45 -50
  112. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -1
  113. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +4 -26
  114. package/contracts/oapps/oft-core/Cargo.toml +1 -4
  115. package/contracts/oapps/oft-core/integration-tests/setup.rs +3 -3
  116. package/contracts/oapps/oft-core/integration-tests/utils.rs +21 -3
  117. package/contracts/oapps/oft-core/src/errors.rs +3 -2
  118. package/contracts/oapps/oft-core/src/events.rs +6 -0
  119. package/contracts/oapps/oft-core/src/lib.rs +1 -1
  120. package/contracts/oapps/oft-core/src/oft_core.rs +341 -246
  121. package/contracts/oapps/oft-core/src/storage.rs +7 -3
  122. package/contracts/oapps/oft-core/src/tests/mod.rs +1 -0
  123. package/contracts/oapps/oft-core/src/tests/test_decimals.rs +37 -2
  124. package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +2 -2
  125. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +323 -0
  126. package/contracts/oapps/oft-core/src/tests/test_send.rs +2 -2
  127. package/contracts/oapps/oft-core/src/tests/test_utils.rs +61 -16
  128. package/contracts/upgrader/src/lib.rs +30 -57
  129. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
  130. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
  131. package/contracts/upgrader/src/tests/test_upgrader.rs +44 -35
  132. package/contracts/utils/Cargo.toml +0 -1
  133. package/contracts/utils/src/buffer_reader.rs +1 -0
  134. package/contracts/utils/src/errors.rs +4 -2
  135. package/contracts/utils/src/multisig.rs +17 -8
  136. package/contracts/utils/src/ownable.rs +6 -6
  137. package/contracts/utils/src/testing_utils.rs +124 -54
  138. package/contracts/utils/src/tests/multisig.rs +12 -12
  139. package/contracts/utils/src/tests/ownable.rs +6 -6
  140. package/contracts/utils/src/tests/testing_utils.rs +50 -167
  141. package/contracts/utils/src/tests/ttl_configurable.rs +5 -5
  142. package/contracts/utils/src/tests/upgradeable.rs +372 -175
  143. package/contracts/utils/src/ttl_configurable.rs +13 -7
  144. package/contracts/utils/src/upgradeable.rs +48 -23
  145. package/contracts/workers/dvn/Cargo.toml +6 -6
  146. package/contracts/workers/dvn/src/auth.rs +12 -42
  147. package/contracts/workers/dvn/src/dvn.rs +15 -40
  148. package/contracts/workers/dvn/src/errors.rs +0 -1
  149. package/contracts/workers/dvn/src/interfaces/dvn.rs +35 -0
  150. package/contracts/workers/dvn/src/lib.rs +4 -3
  151. package/contracts/workers/dvn/src/tests/auth.rs +1 -1
  152. package/contracts/workers/dvn/src/tests/dvn.rs +19 -15
  153. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +2 -4
  154. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +1 -3
  155. package/contracts/workers/dvn/src/tests/setup.rs +5 -9
  156. package/contracts/workers/dvn-fee-lib/Cargo.toml +2 -2
  157. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +38 -22
  158. package/contracts/workers/dvn-fee-lib/src/lib.rs +12 -2
  159. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +17 -16
  160. package/contracts/workers/executor/Cargo.toml +4 -0
  161. package/contracts/workers/executor/src/executor.rs +15 -36
  162. package/contracts/workers/executor/src/lib.rs +2 -2
  163. package/contracts/workers/executor/src/tests/auth.rs +394 -0
  164. package/contracts/workers/executor/src/tests/executor.rs +410 -0
  165. package/contracts/workers/executor/src/tests/mod.rs +3 -0
  166. package/contracts/workers/executor/src/tests/setup.rs +250 -0
  167. package/contracts/workers/executor-fee-lib/Cargo.toml +7 -1
  168. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +62 -15
  169. package/contracts/workers/executor-fee-lib/src/executor_option.rs +28 -1
  170. package/contracts/workers/executor-fee-lib/src/lib.rs +11 -2
  171. package/contracts/workers/executor-fee-lib/src/tests/executor_fee_lib.rs +701 -0
  172. package/contracts/workers/executor-fee-lib/src/tests/executor_option.rs +370 -0
  173. package/contracts/workers/executor-fee-lib/src/tests/mod.rs +4 -0
  174. package/contracts/workers/executor-fee-lib/src/tests/setup.rs +60 -0
  175. package/contracts/workers/executor-helper/Cargo.toml +0 -1
  176. package/contracts/workers/executor-helper/src/lib.rs +3 -0
  177. package/contracts/workers/executor-helper/src/tests/executor_helper.rs +184 -0
  178. package/contracts/workers/executor-helper/src/tests/mod.rs +2 -0
  179. package/contracts/workers/executor-helper/src/tests/setup.rs +366 -0
  180. package/contracts/workers/fee-lib-interfaces/Cargo.toml +14 -0
  181. package/contracts/workers/{worker/src/interfaces/mod.rs → fee-lib-interfaces/src/lib.rs} +4 -3
  182. package/contracts/workers/price-feed/Cargo.toml +7 -1
  183. package/contracts/workers/price-feed/src/events.rs +1 -1
  184. package/contracts/workers/price-feed/src/lib.rs +12 -4
  185. package/contracts/workers/price-feed/src/price_feed.rs +5 -21
  186. package/contracts/workers/price-feed/src/storage.rs +1 -1
  187. package/contracts/workers/price-feed/src/tests/mod.rs +2 -0
  188. package/contracts/workers/price-feed/src/tests/price_feed.rs +869 -0
  189. package/contracts/workers/price-feed/src/tests/setup.rs +70 -0
  190. package/contracts/workers/price-feed/src/types.rs +1 -1
  191. package/contracts/workers/worker/src/errors.rs +1 -4
  192. package/contracts/workers/worker/src/lib.rs +0 -2
  193. package/contracts/workers/worker/src/storage.rs +32 -29
  194. package/contracts/workers/worker/src/tests/setup.rs +2 -8
  195. package/contracts/workers/worker/src/tests/worker.rs +96 -74
  196. package/contracts/workers/worker/src/worker.rs +75 -75
  197. package/docs/error-spec.md +55 -0
  198. package/docs/layerzero-v2-on-stellar.md +447 -0
  199. package/docs/oapp-guide.md +212 -0
  200. package/docs/oft-guide.md +314 -0
  201. package/package.json +3 -3
  202. package/sdk/.turbo/turbo-test.log +268 -263
  203. package/sdk/dist/generated/bml.d.ts +12 -4
  204. package/sdk/dist/generated/bml.js +9 -7
  205. package/sdk/dist/generated/counter.d.ts +306 -298
  206. package/sdk/dist/generated/counter.js +48 -46
  207. package/sdk/dist/generated/dvn.d.ts +450 -411
  208. package/sdk/dist/generated/dvn.js +66 -64
  209. package/sdk/dist/generated/dvn_fee_lib.d.ts +294 -338
  210. package/sdk/dist/generated/dvn_fee_lib.js +33 -64
  211. package/sdk/dist/generated/endpoint.d.ts +108 -100
  212. package/sdk/dist/generated/endpoint.js +21 -19
  213. package/sdk/dist/generated/executor.d.ts +414 -370
  214. package/sdk/dist/generated/executor.js +58 -55
  215. package/sdk/dist/generated/executor_fee_lib.d.ts +333 -377
  216. package/sdk/dist/generated/executor_fee_lib.js +34 -65
  217. package/sdk/dist/generated/executor_helper.d.ts +26 -190
  218. package/sdk/dist/generated/executor_helper.js +23 -28
  219. package/sdk/dist/generated/layerzero_view.d.ts +1271 -0
  220. package/sdk/dist/generated/layerzero_view.js +294 -0
  221. package/sdk/dist/generated/oft.d.ts +408 -385
  222. package/sdk/dist/generated/oft.js +89 -92
  223. package/sdk/dist/generated/price_feed.d.ts +385 -429
  224. package/sdk/dist/generated/price_feed.js +50 -81
  225. package/sdk/dist/generated/sml.d.ts +108 -100
  226. package/sdk/dist/generated/sml.js +21 -19
  227. package/sdk/dist/generated/treasury.d.ts +108 -100
  228. package/sdk/dist/generated/treasury.js +21 -19
  229. package/sdk/dist/generated/uln302.d.ts +108 -100
  230. package/sdk/dist/generated/uln302.js +23 -21
  231. package/sdk/dist/generated/upgrader.d.ts +189 -18
  232. package/sdk/dist/generated/upgrader.js +84 -4
  233. package/sdk/dist/index.d.ts +1 -0
  234. package/sdk/dist/index.js +2 -0
  235. package/sdk/package.json +1 -1
  236. package/sdk/src/index.ts +3 -0
  237. package/sdk/test/oft-sml.test.ts +4 -4
  238. package/sdk/test/suites/localnet.ts +84 -20
  239. package/sdk/test/upgrader.test.ts +2 -3
  240. package/tools/ts-bindings-gen/src/main.rs +2 -1
  241. package/contracts/ERROR_SPEC.md +0 -44
  242. package/contracts/endpoint-v2/ARCHITECTURE.md +0 -233
  243. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +0 -175
  244. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +0 -212
  245. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +0 -153
  246. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +0 -294
  247. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/dvn_fee_lib.rs +0 -0
  248. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/executor_fee_lib.rs +0 -0
  249. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/price_feed.rs +0 -0
@@ -0,0 +1,394 @@
1
+ use super::setup::{Ed25519KeyPair, TestSetup};
2
+ use crate::auth::ExecutorSignature;
3
+ use crate::errors::ExecutorError;
4
+ use soroban_sdk::auth::{Context, ContractContext, CreateContractHostFnContext};
5
+ use soroban_sdk::testutils::Address as _;
6
+ use soroban_sdk::{vec, Address, BytesN, Env, IntoVal, Symbol, Val, Vec};
7
+
8
+ fn mk_sig(setup: &TestSetup<'_>, admin_kp: &Ed25519KeyPair, payload: &BytesN<32>) -> ExecutorSignature {
9
+ ExecutorSignature {
10
+ public_key: admin_kp.public_key(&setup.env),
11
+ signature: admin_kp.sign_payload(&setup.env, payload),
12
+ }
13
+ }
14
+
15
+ fn contract_ctx(env: &Env, contract: Address, fn_name: &str, args: Vec<Val>) -> Context {
16
+ Context::Contract(ContractContext { contract, fn_name: Symbol::new(env, fn_name), args })
17
+ }
18
+
19
+ fn check_auth(
20
+ setup: &TestSetup<'_>,
21
+ payload: &BytesN<32>,
22
+ sig: ExecutorSignature,
23
+ auth_contexts: &Vec<Context>,
24
+ ) -> Result<(), Result<ExecutorError, soroban_sdk::InvokeError>> {
25
+ setup.env.try_invoke_contract_check_auth::<ExecutorError>(
26
+ &setup.contract_id,
27
+ payload,
28
+ sig.into_val(&setup.env),
29
+ auth_contexts,
30
+ )
31
+ }
32
+
33
+ #[test]
34
+ fn test_check_auth_allows_lz_receive_value_zero_single_context() {
35
+ let env = Env::default();
36
+ let admin_kp = Ed25519KeyPair::generate();
37
+ let admin_addr = admin_kp.address(&env);
38
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
39
+
40
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
41
+ let sig = mk_sig(&setup, &admin_kp, &payload);
42
+
43
+ // Executor auth expects `lz_receive`/`lz_compose` contexts and requires the last arg to be `value: i128`.
44
+ // Use value = 0 so only a single context is required.
45
+ let args: Vec<Val> = vec![&setup.env, 0i128.into_val(&setup.env)];
46
+ let oapp = Address::generate(&setup.env);
47
+ let auth_contexts: Vec<Context> = vec![&setup.env, contract_ctx(&setup.env, oapp, "lz_receive", args)];
48
+
49
+ let res = check_auth(&setup, &payload, sig, &auth_contexts);
50
+ assert!(res.is_ok(), "Expected success, got {:?}", res);
51
+ }
52
+
53
+ #[test]
54
+ fn test_check_auth_allows_lz_compose_value_zero_single_context() {
55
+ let env = Env::default();
56
+ let admin_kp = Ed25519KeyPair::generate();
57
+ let admin_addr = admin_kp.address(&env);
58
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
59
+
60
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
61
+ let sig = mk_sig(&setup, &admin_kp, &payload);
62
+
63
+ let args: Vec<Val> = vec![&setup.env, 0i128.into_val(&setup.env)];
64
+ let composer = Address::generate(&setup.env);
65
+ let auth_contexts: Vec<Context> = vec![&setup.env, contract_ctx(&setup.env, composer, "lz_compose", args)];
66
+
67
+ let res = check_auth(&setup, &payload, sig, &auth_contexts);
68
+ assert!(res.is_ok(), "Expected success, got {:?}", res);
69
+ }
70
+
71
+ #[test]
72
+ fn test_check_auth_allows_value_transfer_when_value_nonzero() {
73
+ let env = Env::default();
74
+ let admin_kp = Ed25519KeyPair::generate();
75
+ let admin_addr = admin_kp.address(&env);
76
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
77
+
78
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
79
+ let sig = mk_sig(&setup, &admin_kp, &payload);
80
+
81
+ let value: i128 = 123;
82
+ let oapp = Address::generate(&setup.env);
83
+ let exec_args: Vec<Val> = vec![&setup.env, value.into_val(&setup.env)];
84
+
85
+ let from = Address::generate(&setup.env);
86
+ let to = Address::generate(&setup.env);
87
+ let transfer_args: Vec<Val> =
88
+ vec![&setup.env, from.into_val(&setup.env), to.into_val(&setup.env), value.into_val(&setup.env)];
89
+
90
+ let auth_contexts: Vec<Context> = vec![
91
+ &setup.env,
92
+ contract_ctx(&setup.env, oapp, "lz_receive", exec_args),
93
+ contract_ctx(&setup.env, setup.native_token.clone(), "transfer", transfer_args),
94
+ ];
95
+
96
+ let res = check_auth(&setup, &payload, sig, &auth_contexts);
97
+ assert!(res.is_ok(), "Expected success, got {:?}", res);
98
+ }
99
+
100
+ #[test]
101
+ fn test_check_auth_allows_alert_calls_only_on_endpoint() {
102
+ let env = Env::default();
103
+ let admin_kp = Ed25519KeyPair::generate();
104
+ let admin_addr = admin_kp.address(&env);
105
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
106
+
107
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
108
+ let sig = mk_sig(&setup, &admin_kp, &payload);
109
+
110
+ let empty_args: Vec<Val> = Vec::new(&setup.env);
111
+ for fn_name in ["lz_receive_alert", "lz_compose_alert"] {
112
+ let contexts: Vec<Context> =
113
+ vec![&setup.env, contract_ctx(&setup.env, setup.endpoint.clone(), fn_name, empty_args.clone())];
114
+ let res = check_auth(&setup, &payload, sig.clone(), &contexts);
115
+ assert!(res.is_ok(), "Expected success for {fn_name}, got {:?}", res);
116
+ }
117
+ }
118
+
119
+ #[test]
120
+ fn test_check_auth_rejects_signature_mismatch() {
121
+ let env = Env::default();
122
+ let admin_kp = Ed25519KeyPair::generate();
123
+ let admin_addr = admin_kp.address(&env);
124
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
125
+
126
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
127
+ let other_kp = Ed25519KeyPair::generate();
128
+
129
+ // Admin pubkey is registered, but signature is produced by a different key.
130
+ let sig = ExecutorSignature {
131
+ public_key: admin_kp.public_key(&setup.env),
132
+ signature: other_kp.sign_payload(&setup.env, &payload),
133
+ };
134
+
135
+ let oapp = Address::generate(&setup.env);
136
+ let args: Vec<Val> = vec![&setup.env, 0i128.into_val(&setup.env)];
137
+ let contexts: Vec<Context> = vec![&setup.env, contract_ctx(&setup.env, oapp, "lz_receive", args)];
138
+
139
+ let res = check_auth(&setup, &payload, sig, &contexts);
140
+ assert!(matches!(res, Err(Err(_))), "Expected host error, got {:?}", res);
141
+ }
142
+
143
+ #[test]
144
+ fn test_check_auth_rejects_non_admin() {
145
+ let env = Env::default();
146
+ let admin_kp = Ed25519KeyPair::generate();
147
+ let admin_addr = admin_kp.address(&env);
148
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
149
+
150
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
151
+ let oapp = Address::generate(&setup.env);
152
+ let args: Vec<Val> = vec![&setup.env, 0i128.into_val(&setup.env)];
153
+ let contexts: Vec<Context> = vec![&setup.env, contract_ctx(&setup.env, oapp, "lz_receive", args)];
154
+
155
+ // Unauthorized: signer not in admins list
156
+ let non_admin_kp = Ed25519KeyPair::generate();
157
+ let sig = ExecutorSignature {
158
+ public_key: non_admin_kp.public_key(&setup.env),
159
+ signature: non_admin_kp.sign_payload(&setup.env, &payload),
160
+ };
161
+
162
+ let res = check_auth(&setup, &payload, sig, &contexts);
163
+ assert_eq!(res, Err(Ok(ExecutorError::Unauthorized)));
164
+ }
165
+
166
+ #[test]
167
+ fn test_check_auth_rejects_empty_or_too_many_contexts() {
168
+ let env = Env::default();
169
+ let admin_kp = Ed25519KeyPair::generate();
170
+ let admin_addr = admin_kp.address(&env);
171
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
172
+
173
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
174
+ let sig = mk_sig(&setup, &admin_kp, &payload);
175
+
176
+ // Empty contexts
177
+ let empty: Vec<Context> = Vec::new(&setup.env);
178
+ assert_eq!(check_auth(&setup, &payload, sig.clone(), &empty), Err(Ok(ExecutorError::UnauthorizedContext)));
179
+
180
+ // Too many contexts (>2)
181
+ let oapp = Address::generate(&setup.env);
182
+ let args0: Vec<Val> = vec![&setup.env, 0i128.into_val(&setup.env)];
183
+ let too_many: Vec<Context> = vec![
184
+ &setup.env,
185
+ contract_ctx(&setup.env, oapp.clone(), "lz_receive", args0.clone()),
186
+ contract_ctx(&setup.env, oapp.clone(), "lz_receive", args0.clone()),
187
+ contract_ctx(&setup.env, oapp, "lz_receive", args0),
188
+ ];
189
+ assert_eq!(check_auth(&setup, &payload, sig, &too_many), Err(Ok(ExecutorError::UnauthorizedContext)));
190
+ }
191
+
192
+ #[test]
193
+ fn test_check_auth_rejects_non_contract_first_context() {
194
+ let env = Env::default();
195
+ let admin_kp = Ed25519KeyPair::generate();
196
+ let admin_addr = admin_kp.address(&env);
197
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
198
+
199
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
200
+ let sig = mk_sig(&setup, &admin_kp, &payload);
201
+
202
+ let create_ctx: Vec<Context> = vec![
203
+ &setup.env,
204
+ Context::CreateContractHostFn(CreateContractHostFnContext {
205
+ executable: soroban_sdk::auth::ContractExecutable::Wasm(BytesN::from_array(&setup.env, &[2u8; 32])),
206
+ salt: BytesN::from_array(&setup.env, &[3u8; 32]),
207
+ }),
208
+ ];
209
+ assert_eq!(check_auth(&setup, &payload, sig, &create_ctx), Err(Ok(ExecutorError::UnauthorizedContext)));
210
+ }
211
+
212
+ #[test]
213
+ fn test_check_auth_rejects_invalid_execute_fn_name() {
214
+ let env = Env::default();
215
+ let admin_kp = Ed25519KeyPair::generate();
216
+ let admin_addr = admin_kp.address(&env);
217
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
218
+
219
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
220
+ let sig = mk_sig(&setup, &admin_kp, &payload);
221
+
222
+ let oapp = Address::generate(&setup.env);
223
+ let bad_fn: Vec<Context> =
224
+ vec![&setup.env, contract_ctx(&setup.env, oapp, "not_allowed", vec![&setup.env, 0i128.into_val(&setup.env)])];
225
+ assert_eq!(check_auth(&setup, &payload, sig, &bad_fn), Err(Ok(ExecutorError::UnauthorizedContext)));
226
+ }
227
+
228
+ #[test]
229
+ fn test_check_auth_rejects_invalid_alert_contexts() {
230
+ let env = Env::default();
231
+ let admin_kp = Ed25519KeyPair::generate();
232
+ let admin_addr = admin_kp.address(&env);
233
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
234
+
235
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
236
+ let sig = mk_sig(&setup, &admin_kp, &payload);
237
+
238
+ let oapp = Address::generate(&setup.env);
239
+
240
+ // Alert fn must target endpoint and must be the only context
241
+ let bad_alert_contract: Vec<Context> =
242
+ vec![&setup.env, contract_ctx(&setup.env, oapp.clone(), "lz_receive_alert", Vec::new(&setup.env))];
243
+ assert_eq!(
244
+ check_auth(&setup, &payload, sig.clone(), &bad_alert_contract),
245
+ Err(Ok(ExecutorError::UnauthorizedContext))
246
+ );
247
+
248
+ let bad_alert_extra_ctx: Vec<Context> = vec![
249
+ &setup.env,
250
+ contract_ctx(&setup.env, setup.endpoint.clone(), "lz_receive_alert", Vec::new(&setup.env)),
251
+ contract_ctx(&setup.env, oapp, "lz_receive", vec![&setup.env, 0i128.into_val(&setup.env)]),
252
+ ];
253
+ assert_eq!(check_auth(&setup, &payload, sig, &bad_alert_extra_ctx), Err(Ok(ExecutorError::UnauthorizedContext)));
254
+ }
255
+
256
+ #[test]
257
+ fn test_check_auth_rejects_execute_missing_or_wrong_value_type() {
258
+ let env = Env::default();
259
+ let admin_kp = Ed25519KeyPair::generate();
260
+ let admin_addr = admin_kp.address(&env);
261
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
262
+
263
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
264
+ let sig = mk_sig(&setup, &admin_kp, &payload);
265
+
266
+ let oapp = Address::generate(&setup.env);
267
+
268
+ // Execute path requires last arg to be i128 value
269
+ let missing_value: Vec<Context> =
270
+ vec![&setup.env, contract_ctx(&setup.env, oapp.clone(), "lz_receive", Vec::new(&setup.env))];
271
+ assert_eq!(check_auth(&setup, &payload, sig.clone(), &missing_value), Err(Ok(ExecutorError::UnauthorizedContext)));
272
+
273
+ let wrong_value_type: Vec<Context> = vec![
274
+ &setup.env,
275
+ contract_ctx(
276
+ &setup.env,
277
+ oapp,
278
+ "lz_receive",
279
+ vec![&setup.env, Symbol::new(&setup.env, "not_i128").into_val(&setup.env)],
280
+ ),
281
+ ];
282
+ assert_eq!(check_auth(&setup, &payload, sig, &wrong_value_type), Err(Ok(ExecutorError::UnauthorizedContext)));
283
+ }
284
+
285
+ #[test]
286
+ fn test_check_auth_rejects_value_zero_with_extra_context() {
287
+ let env = Env::default();
288
+ let admin_kp = Ed25519KeyPair::generate();
289
+ let admin_addr = admin_kp.address(&env);
290
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
291
+
292
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
293
+ let sig = mk_sig(&setup, &admin_kp, &payload);
294
+
295
+ let oapp = Address::generate(&setup.env);
296
+ let value_zero_with_transfer: Vec<Context> = vec![
297
+ &setup.env,
298
+ contract_ctx(&setup.env, oapp, "lz_receive", vec![&setup.env, 0i128.into_val(&setup.env)]),
299
+ contract_ctx(
300
+ &setup.env,
301
+ setup.native_token.clone(),
302
+ "transfer",
303
+ vec![
304
+ &setup.env,
305
+ Address::generate(&setup.env).into_val(&setup.env),
306
+ Address::generate(&setup.env).into_val(&setup.env),
307
+ 1i128.into_val(&setup.env),
308
+ ],
309
+ ),
310
+ ];
311
+ assert_eq!(
312
+ check_auth(&setup, &payload, sig, &value_zero_with_transfer),
313
+ Err(Ok(ExecutorError::UnauthorizedContext))
314
+ );
315
+ }
316
+
317
+ #[test]
318
+ fn test_check_auth_rejects_value_nonzero_missing_transfer_context() {
319
+ let env = Env::default();
320
+ let admin_kp = Ed25519KeyPair::generate();
321
+ let admin_addr = admin_kp.address(&env);
322
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
323
+
324
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
325
+ let sig = mk_sig(&setup, &admin_kp, &payload);
326
+
327
+ let oapp = Address::generate(&setup.env);
328
+ let value_nonzero_missing_transfer: Vec<Context> =
329
+ vec![&setup.env, contract_ctx(&setup.env, oapp, "lz_receive", vec![&setup.env, 1i128.into_val(&setup.env)])];
330
+ assert_eq!(
331
+ check_auth(&setup, &payload, sig, &value_nonzero_missing_transfer),
332
+ Err(Ok(ExecutorError::UnauthorizedContext))
333
+ );
334
+ }
335
+
336
+ #[test]
337
+ fn test_check_auth_rejects_invalid_transfer_context() {
338
+ let env = Env::default();
339
+ let admin_kp = Ed25519KeyPair::generate();
340
+ let admin_addr = admin_kp.address(&env);
341
+ let setup = TestSetup::new_with_env_and_admin(env, &admin_addr);
342
+
343
+ let payload = BytesN::from_array(&setup.env, &[1u8; 32]);
344
+ let sig = mk_sig(&setup, &admin_kp, &payload);
345
+
346
+ let oapp = Address::generate(&setup.env);
347
+ let base_exec: Context = contract_ctx(&setup.env, oapp, "lz_receive", vec![&setup.env, 5i128.into_val(&setup.env)]);
348
+ let transfer_args: Vec<Val> = vec![
349
+ &setup.env,
350
+ Address::generate(&setup.env).into_val(&setup.env),
351
+ Address::generate(&setup.env).into_val(&setup.env),
352
+ 5i128.into_val(&setup.env),
353
+ ];
354
+
355
+ // Wrong transfer fn name
356
+ let wrong_transfer_fn: Vec<Context> = vec![
357
+ &setup.env,
358
+ base_exec.clone(),
359
+ contract_ctx(&setup.env, setup.native_token.clone(), "not_transfer", transfer_args.clone()),
360
+ ];
361
+ assert_eq!(
362
+ check_auth(&setup, &payload, sig.clone(), &wrong_transfer_fn),
363
+ Err(Ok(ExecutorError::UnauthorizedContext))
364
+ );
365
+
366
+ // Wrong transfer contract
367
+ let wrong_transfer_contract: Vec<Context> = vec![
368
+ &setup.env,
369
+ base_exec.clone(),
370
+ contract_ctx(&setup.env, Address::generate(&setup.env), "transfer", transfer_args.clone()),
371
+ ];
372
+ assert_eq!(
373
+ check_auth(&setup, &payload, sig.clone(), &wrong_transfer_contract),
374
+ Err(Ok(ExecutorError::UnauthorizedContext))
375
+ );
376
+
377
+ // Wrong transfer amount (must match value)
378
+ let wrong_transfer_amount: Vec<Context> = vec![
379
+ &setup.env,
380
+ base_exec,
381
+ contract_ctx(
382
+ &setup.env,
383
+ setup.native_token.clone(),
384
+ "transfer",
385
+ vec![
386
+ &setup.env,
387
+ Address::generate(&setup.env).into_val(&setup.env),
388
+ Address::generate(&setup.env).into_val(&setup.env),
389
+ 6i128.into_val(&setup.env),
390
+ ],
391
+ ),
392
+ ];
393
+ assert_eq!(check_auth(&setup, &payload, sig, &wrong_transfer_amount), Err(Ok(ExecutorError::UnauthorizedContext)));
394
+ }