@layerzerolabs/protocol-stellar-v2 0.2.29 → 0.2.30

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 (205) hide show
  1. package/.turbo/turbo-build.log +371 -321
  2. package/.turbo/turbo-lint.log +211 -202
  3. package/.turbo/turbo-test.log +1766 -1673
  4. package/Cargo.lock +11 -1
  5. package/contracts/common-macros/src/lib.rs +0 -2
  6. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +1 -0
  7. package/contracts/endpoint-v2/src/messaging_channel.rs +32 -3
  8. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +1 -1
  9. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +1 -1
  10. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +6 -6
  11. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +1 -1
  12. package/contracts/endpoint-v2/src/tests/messaging_channel/outbound.rs +16 -10
  13. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +10 -10
  14. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +3 -3
  15. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +4 -3
  16. package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +1 -57
  17. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +0 -30
  18. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -3
  19. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +6 -4
  20. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -3
  21. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -3
  22. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +0 -30
  23. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +0 -30
  24. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/basic.rs +0 -2
  25. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/multisig_contract.rs +0 -2
  26. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_migration.rs +0 -2
  27. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_user_contractimpl.rs +1 -3
  28. package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +3 -6
  29. package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +10 -0
  30. package/contracts/message-libs/message-lib-common/src/worker_options.rs +6 -2
  31. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +3 -3
  32. package/contracts/message-libs/treasury/src/lib.rs +2 -1
  33. package/contracts/message-libs/treasury/src/tests/setup.rs +1 -1
  34. package/contracts/message-libs/treasury/src/treasury.rs +5 -2
  35. package/contracts/message-libs/uln-302/src/errors.rs +2 -0
  36. package/contracts/message-libs/uln-302/src/events.rs +3 -3
  37. package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +8 -0
  38. package/contracts/message-libs/uln-302/src/lib.rs +2 -1
  39. package/contracts/message-libs/uln-302/src/receive_uln.rs +16 -13
  40. package/contracts/message-libs/uln-302/src/send_uln.rs +51 -24
  41. package/contracts/message-libs/uln-302/src/storage.rs +2 -2
  42. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +45 -1
  43. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +63 -0
  44. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +47 -2
  45. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +50 -1
  46. package/contracts/message-libs/uln-302/src/uln302.rs +0 -8
  47. package/contracts/oapps/counter/Cargo.toml +4 -4
  48. package/contracts/oapps/counter/integration_tests/setup_uln.rs +22 -2
  49. package/contracts/oapps/counter/src/counter.rs +8 -8
  50. package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +33 -10
  51. package/contracts/oapps/oapp/src/lib.rs +6 -2
  52. package/contracts/oapps/oapp/src/oapp_core.rs +49 -24
  53. package/contracts/oapps/oapp/src/oapp_options_type3.rs +21 -14
  54. package/contracts/oapps/oapp/src/oapp_receiver.rs +17 -16
  55. package/contracts/oapps/oapp/src/oapp_sender.rs +66 -15
  56. package/contracts/oapps/oapp/src/tests/oapp_core.rs +5 -5
  57. package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +18 -18
  58. package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +4 -4
  59. package/contracts/oapps/oapp/src/tests/oapp_sender.rs +3 -3
  60. package/contracts/oapps/oapp-macros/Cargo.toml +0 -1
  61. package/contracts/oapps/oapp-macros/src/generators.rs +87 -46
  62. package/contracts/oapps/oapp-macros/src/lib.rs +3 -61
  63. package/contracts/oapps/oapp-macros/src/tests/oapp.rs +9 -23
  64. package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +15 -11
  65. package/contracts/oapps/oft/Cargo.toml +1 -1
  66. package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +3 -3
  67. package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +4 -4
  68. package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +144 -8
  69. package/contracts/oapps/oft/integration-tests/setup.rs +4 -2
  70. package/contracts/oapps/oft/integration-tests/utils.rs +25 -11
  71. package/contracts/oapps/oft/src/extensions/oft_fee.rs +65 -63
  72. package/contracts/oapps/oft/src/extensions/pausable.rs +2 -3
  73. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +22 -5
  74. package/contracts/oapps/oft/src/interfaces/mint_burnable.rs +18 -0
  75. package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
  76. package/contracts/oapps/oft/src/lib.rs +4 -2
  77. package/contracts/oapps/oft/src/oft.rs +35 -36
  78. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +13 -9
  79. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +14 -9
  80. package/contracts/oapps/oft/src/oft_types/mod.rs +14 -12
  81. package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +28 -20
  82. package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +136 -2
  83. package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +12 -8
  84. package/contracts/oapps/oft-core/integration-tests/setup.rs +8 -9
  85. package/contracts/oapps/oft-core/integration-tests/test_with_sml.rs +7 -6
  86. package/contracts/oapps/oft-core/integration-tests/utils.rs +5 -4
  87. package/contracts/oapps/oft-core/src/codec/oft_compose_msg_codec.rs +2 -2
  88. package/contracts/oapps/oft-core/src/codec/oft_msg_codec.rs +33 -37
  89. package/contracts/oapps/oft-core/src/errors.rs +2 -1
  90. package/contracts/oapps/oft-core/src/events.rs +6 -0
  91. package/contracts/oapps/oft-core/src/lib.rs +8 -4
  92. package/contracts/oapps/oft-core/src/oft_core.rs +205 -148
  93. package/contracts/oapps/oft-core/src/storage.rs +4 -2
  94. package/contracts/oapps/oft-core/src/tests/test_decimals.rs +2 -2
  95. package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +6 -6
  96. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +7 -6
  97. package/contracts/oapps/oft-core/src/tests/test_oft_msg_codec.rs +11 -82
  98. package/contracts/oapps/oft-core/src/tests/test_quote_oft.rs +13 -13
  99. package/contracts/oapps/oft-core/src/tests/test_quote_send.rs +1 -1
  100. package/contracts/oapps/oft-core/src/tests/test_resolve_address.rs +2 -2
  101. package/contracts/oapps/oft-core/src/tests/test_send.rs +22 -22
  102. package/contracts/oapps/oft-core/src/tests/test_utils.rs +20 -22
  103. package/contracts/oapps/oft-core/src/utils.rs +12 -8
  104. package/contracts/sac-manager/Cargo.toml +25 -0
  105. package/contracts/sac-manager/src/errors.rs +18 -0
  106. package/contracts/sac-manager/src/extensions/mod.rs +6 -0
  107. package/contracts/sac-manager/src/extensions/redistribution.rs +109 -0
  108. package/contracts/sac-manager/src/extensions/supply_control/mod.rs +488 -0
  109. package/contracts/sac-manager/src/extensions/supply_control/rate_limit.rs +126 -0
  110. package/contracts/sac-manager/src/interfaces/mod.rs +3 -0
  111. package/contracts/sac-manager/src/interfaces/sac_manager.rs +52 -0
  112. package/contracts/sac-manager/src/lib.rs +23 -0
  113. package/contracts/sac-manager/src/sac_manager.rs +193 -0
  114. package/contracts/sac-manager/src/storage.rs +20 -0
  115. package/contracts/sac-manager/src/tests/mod.rs +14 -0
  116. package/contracts/sac-manager/src/tests/redistribution/mod.rs +1 -0
  117. package/contracts/sac-manager/src/tests/redistribution/redistribute_funds.rs +82 -0
  118. package/contracts/sac-manager/src/tests/sac_manager/admin_mint.rs +206 -0
  119. package/contracts/sac-manager/src/tests/sac_manager/burn.rs +215 -0
  120. package/contracts/sac-manager/src/tests/sac_manager/clawback.rs +209 -0
  121. package/contracts/sac-manager/src/tests/sac_manager/mint.rs +252 -0
  122. package/contracts/sac-manager/src/tests/sac_manager/mod.rs +9 -0
  123. package/contracts/sac-manager/src/tests/sac_manager/set_admin.rs +36 -0
  124. package/contracts/sac-manager/src/tests/sac_manager/set_authorized.rs +43 -0
  125. package/contracts/sac-manager/src/tests/sac_manager/set_oft_address.rs +47 -0
  126. package/contracts/sac-manager/src/tests/sac_manager/test_helper.rs +75 -0
  127. package/contracts/sac-manager/src/tests/sac_manager/view_functions.rs +60 -0
  128. package/contracts/sac-manager/src/tests/supply_control/enumerable_set.rs +256 -0
  129. package/contracts/sac-manager/src/tests/supply_control/mod.rs +8 -0
  130. package/contracts/sac-manager/src/tests/supply_control/refill.rs +90 -0
  131. package/contracts/sac-manager/src/tests/supply_control/set_mint_whitelist.rs +245 -0
  132. package/contracts/sac-manager/src/tests/supply_control/set_supply_controller.rs +267 -0
  133. package/contracts/sac-manager/src/tests/supply_control/set_supply_controller_manager.rs +122 -0
  134. package/contracts/sac-manager/src/tests/supply_control/test_helper.rs +38 -0
  135. package/contracts/sac-manager/src/tests/supply_control/update_allow_any_mint_burn.rs +114 -0
  136. package/contracts/sac-manager/src/tests/supply_control/update_limit_config.rs +257 -0
  137. package/contracts/sac-manager/src/tests/test_helper.rs +190 -0
  138. package/contracts/upgrader/src/lib.rs +2 -1
  139. package/contracts/utils/src/errors.rs +0 -1
  140. package/contracts/utils/src/tests/upgradeable.rs +0 -66
  141. package/contracts/utils/src/upgradeable.rs +0 -18
  142. package/contracts/workers/dvn/src/dvn.rs +2 -2
  143. package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
  144. package/contracts/workers/dvn/src/lib.rs +2 -1
  145. package/contracts/workers/dvn-fee-lib/src/lib.rs +3 -1
  146. package/contracts/workers/executor/src/auth.rs +42 -26
  147. package/contracts/workers/executor/src/executor.rs +28 -3
  148. package/contracts/workers/executor/src/lib.rs +4 -2
  149. package/contracts/workers/executor/src/storage.rs +21 -1
  150. package/contracts/workers/executor/src/tests/auth.rs +64 -20
  151. package/contracts/workers/executor/src/tests/executor.rs +1 -1
  152. package/contracts/workers/executor/src/tests/setup.rs +18 -0
  153. package/contracts/workers/executor-fee-lib/src/lib.rs +4 -1
  154. package/contracts/workers/executor-helper/src/executor_helper.rs +24 -10
  155. package/contracts/workers/executor-helper/src/tests/setup.rs +147 -34
  156. package/contracts/workers/price-feed/src/lib.rs +3 -1
  157. package/contracts/workers/worker/src/lib.rs +2 -1
  158. package/contracts/workers/worker/src/worker.rs +31 -17
  159. package/docs/oapp-guide.md +17 -8
  160. package/docs/oft-guide.md +3 -3
  161. package/package.json +3 -3
  162. package/sdk/.turbo/turbo-test.log +512 -351
  163. package/sdk/dist/generated/bml.d.ts +3 -9
  164. package/sdk/dist/generated/bml.js +6 -7
  165. package/sdk/dist/generated/counter.d.ts +22 -28
  166. package/sdk/dist/generated/counter.js +11 -12
  167. package/sdk/dist/generated/dvn.d.ts +36 -54
  168. package/sdk/dist/generated/dvn.js +10 -15
  169. package/sdk/dist/generated/dvn_fee_lib.d.ts +3 -21
  170. package/sdk/dist/generated/dvn_fee_lib.js +6 -11
  171. package/sdk/dist/generated/endpoint.d.ts +3 -9
  172. package/sdk/dist/generated/endpoint.js +6 -7
  173. package/sdk/dist/generated/executor.d.ts +80 -54
  174. package/sdk/dist/generated/executor.js +16 -16
  175. package/sdk/dist/generated/executor_fee_lib.d.ts +3 -21
  176. package/sdk/dist/generated/executor_fee_lib.js +6 -11
  177. package/sdk/dist/generated/executor_helper.d.ts +36 -42
  178. package/sdk/dist/generated/executor_helper.js +9 -10
  179. package/sdk/dist/generated/layerzero_view.d.ts +20 -32
  180. package/sdk/dist/generated/layerzero_view.js +25 -26
  181. package/sdk/dist/generated/oft.d.ts +147 -79
  182. package/sdk/dist/generated/oft.js +47 -54
  183. package/sdk/dist/generated/price_feed.d.ts +20 -38
  184. package/sdk/dist/generated/price_feed.js +15 -20
  185. package/sdk/dist/generated/sac_manager.d.ts +1309 -0
  186. package/sdk/dist/generated/sac_manager.js +484 -0
  187. package/sdk/dist/generated/sml.d.ts +3 -9
  188. package/sdk/dist/generated/sml.js +6 -7
  189. package/sdk/dist/generated/treasury.d.ts +3 -9
  190. package/sdk/dist/generated/treasury.js +8 -9
  191. package/sdk/dist/generated/uln302.d.ts +20 -20
  192. package/sdk/dist/generated/uln302.js +25 -22
  193. package/sdk/dist/generated/upgrader.d.ts +3 -9
  194. package/sdk/dist/generated/upgrader.js +6 -7
  195. package/sdk/dist/index.d.ts +1 -0
  196. package/sdk/dist/index.js +1 -0
  197. package/sdk/package.json +1 -1
  198. package/sdk/src/index.ts +1 -0
  199. package/sdk/test/oft-sml.test.ts +7 -5
  200. package/sdk/test/sac-manager-redistribution.test.ts +578 -0
  201. package/sdk/test/suites/globalSetup.ts +11 -6
  202. package/sdk/test/test_data/test_upgradeable_dvn.wasm +0 -0
  203. package/sdk/test/upgrader.test.ts +75 -202
  204. package/sdk/test/utils.ts +40 -0
  205. package/tools/ts-bindings-gen/src/main.rs +1 -0
@@ -6,7 +6,7 @@ use quote::quote;
6
6
 
7
7
  #[test]
8
8
  fn test_custom_impls_parse_empty_is_default() {
9
- let parsed: crate::CustomImpls = syn::parse2(quote! {}).expect("failed to parse empty attrs");
9
+ let parsed: crate::generators::CustomImpls = syn::parse2(quote! {}).expect("failed to parse empty attrs");
10
10
  assert!(!parsed.core);
11
11
  assert!(!parsed.sender);
12
12
  assert!(!parsed.receiver);
@@ -15,7 +15,7 @@ fn test_custom_impls_parse_empty_is_default() {
15
15
 
16
16
  #[test]
17
17
  fn test_custom_impls_parse_valid_all_list() {
18
- let parsed: crate::CustomImpls =
18
+ let parsed: crate::generators::CustomImpls =
19
19
  syn::parse2(quote! { custom = [core, sender, receiver, options_type3] }).expect("failed to parse attrs");
20
20
  assert!(parsed.core);
21
21
  assert!(parsed.sender);
@@ -25,7 +25,7 @@ fn test_custom_impls_parse_valid_all_list() {
25
25
 
26
26
  #[test]
27
27
  fn test_custom_impls_parse_empty_custom_list_is_default() {
28
- let parsed: crate::CustomImpls = syn::parse2(quote! { custom = [] }).expect("failed to parse attrs");
28
+ let parsed: crate::generators::CustomImpls = syn::parse2(quote! { custom = [] }).expect("failed to parse attrs");
29
29
  assert!(!parsed.core);
30
30
  assert!(!parsed.sender);
31
31
  assert!(!parsed.receiver);
@@ -34,7 +34,8 @@ fn test_custom_impls_parse_empty_custom_list_is_default() {
34
34
 
35
35
  #[test]
36
36
  fn test_custom_impls_allows_trailing_comma() {
37
- let parsed: crate::CustomImpls = syn::parse2(quote! { custom = [core,] }).expect("failed to parse attrs");
37
+ let parsed: crate::generators::CustomImpls =
38
+ syn::parse2(quote! { custom = [core,] }).expect("failed to parse attrs");
38
39
  assert!(parsed.core);
39
40
  assert!(!parsed.sender);
40
41
  assert!(!parsed.receiver);
@@ -44,7 +45,7 @@ fn test_custom_impls_allows_trailing_comma() {
44
45
  #[test]
45
46
  fn test_custom_impls_allows_duplicates() {
46
47
  // Duplicates are harmless and should not cause parsing to fail.
47
- let parsed: crate::CustomImpls =
48
+ let parsed: crate::generators::CustomImpls =
48
49
  syn::parse2(quote! { custom = [core, core, receiver, receiver] }).expect("failed to parse attrs");
49
50
  assert!(parsed.core);
50
51
  assert!(!parsed.sender);
@@ -54,14 +55,15 @@ fn test_custom_impls_allows_duplicates() {
54
55
 
55
56
  #[test]
56
57
  fn test_custom_impls_rejects_wrong_key() {
57
- let err = syn::parse2::<crate::CustomImpls>(quote! { nope = [core] }).expect_err("expected parse failure");
58
+ let err =
59
+ syn::parse2::<crate::generators::CustomImpls>(quote! { nope = [core] }).expect_err("expected parse failure");
58
60
  assert!(err.to_string().contains("expected `custom`"), "unexpected error: {err}");
59
61
  }
60
62
 
61
63
  #[test]
62
64
  fn test_custom_impls_rejects_unknown_ident() {
63
- let err =
64
- syn::parse2::<crate::CustomImpls>(quote! { custom = [core, not_a_real_option] }).expect_err("expected failure");
65
+ let err = syn::parse2::<crate::generators::CustomImpls>(quote! { custom = [core, not_a_real_option] })
66
+ .expect_err("expected failure");
65
67
  assert!(
66
68
  err.to_string().contains("expected one of `core`, `sender`, `receiver`, `options_type3`"),
67
69
  "unexpected error: {err}"
@@ -71,16 +73,18 @@ fn test_custom_impls_rejects_unknown_ident() {
71
73
  #[test]
72
74
  fn test_custom_impls_rejects_trailing_tokens_after_list() {
73
75
  // `syn::parse2` expects the parser to consume the full stream.
74
- syn::parse2::<crate::CustomImpls>(quote! { custom = [core] extra })
76
+ syn::parse2::<crate::generators::CustomImpls>(quote! { custom = [core] extra })
75
77
  .expect_err("expected parse failure due to trailing tokens");
76
78
  }
77
79
 
78
80
  #[test]
79
81
  fn test_custom_impls_rejects_missing_equals() {
80
- syn::parse2::<crate::CustomImpls>(quote! { custom [core] }).expect_err("expected parse failure (missing `=`)");
82
+ syn::parse2::<crate::generators::CustomImpls>(quote! { custom [core] })
83
+ .expect_err("expected parse failure (missing `=`)");
81
84
  }
82
85
 
83
86
  #[test]
84
87
  fn test_custom_impls_rejects_non_bracketed_list() {
85
- syn::parse2::<crate::CustomImpls>(quote! { custom = (core) }).expect_err("expected parse failure (not `[...]`)");
88
+ syn::parse2::<crate::generators::CustomImpls>(quote! { custom = (core) })
89
+ .expect_err("expected parse failure (not `[...]`)");
86
90
  }
@@ -24,7 +24,7 @@ oft-core = { workspace = true }
24
24
 
25
25
  [dev-dependencies]
26
26
  soroban-sdk = { workspace = true, features = ["testutils"] }
27
- simple-message-lib = { workspace = true }
27
+ simple-message-lib = { workspace = true, features = ["testutils"] }
28
28
  message-lib-common = { workspace = true, features = ["testutils"] }
29
29
  endpoint-v2 = { workspace = true, features = ["testutils"] }
30
30
  utils = { workspace = true, features = ["testutils"] }
@@ -33,7 +33,7 @@ fn test_cross_chain_with_zero_fee() {
33
33
 
34
34
  let to = address_to_peer_bytes32(&receiver);
35
35
  let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
36
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
36
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
37
37
 
38
38
  // With zero fee, amount_sent_ld == amount_received_ld (after dust removal)
39
39
  assert_eq!(oft_receipt.amount_sent_ld, oft_receipt.amount_received_ld);
@@ -75,7 +75,7 @@ fn test_cross_chain_with_fee() {
75
75
  let to = address_to_peer_bytes32(&receiver);
76
76
  let amount_ld = 1_000_000i128;
77
77
  let send_param = create_send_param(&env, chain_b.eid, amount_ld, 0, &to);
78
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
78
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
79
79
 
80
80
  // With fee, amount_sent_ld stays original, amount_received_ld is reduced
81
81
  assert_eq!(oft_receipt.amount_sent_ld, amount_ld);
@@ -129,7 +129,7 @@ fn test_cross_chain_with_destination_specific_fee() {
129
129
  let to = address_to_peer_bytes32(&receiver);
130
130
  let amount_ld = 1_000_000i128;
131
131
  let send_param = create_send_param(&env, chain_b.eid, amount_ld, 0, &to);
132
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
132
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
133
133
 
134
134
  // 2% fee on 1,000,000 = 20,000
135
135
  let expected_fee = 20_000i128;
@@ -33,7 +33,7 @@ fn test_send_succeeds_when_unpaused() {
33
33
 
34
34
  let to = address_to_peer_bytes32(&receiver);
35
35
  let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
36
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
36
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
37
37
  let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
38
38
 
39
39
  send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
@@ -71,7 +71,7 @@ fn test_send_fails_when_paused() {
71
71
  let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
72
72
 
73
73
  // Get quote BEFORE pausing (since quote_oft also checks pause state)
74
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
74
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
75
75
  let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
76
76
 
77
77
  // Pause the OFT
@@ -102,7 +102,7 @@ fn test_receive_fails_when_paused() {
102
102
  // Send from chain_a to chain_b
103
103
  let to = address_to_peer_bytes32(&receiver);
104
104
  let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
105
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
105
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
106
106
  let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
107
107
  send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
108
108
 
@@ -144,7 +144,7 @@ fn test_cross_chain_succeeds_after_unpause() {
144
144
  // Send should work after unpause
145
145
  let to = address_to_peer_bytes32(&receiver);
146
146
  let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
147
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
147
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
148
148
  let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
149
149
 
150
150
  send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
@@ -3,13 +3,13 @@
3
3
  //! Tests verify that the RateLimiter extension properly enforces rate limits
4
4
  //! on cross-chain transfers. Uses real EndpointV2 and SimpleMessageLib.
5
5
 
6
- use crate::extensions::rate_limiter::Direction;
6
+ use crate::extensions::rate_limiter::{Direction, Mode};
7
7
  use crate::integration_tests::{
8
8
  setup::{create_recipient_address, decode_packet, setup, wire_endpoint, wire_oft, TestSetup},
9
9
  utils::{
10
10
  address_to_peer_bytes32, advance_time, create_send_param, lz_receive, mint_to, quote_oft, quote_send,
11
- rate_limit_capacity, rate_limit_in_flight, scan_packet_sent_event, send, set_rate_limit, transfer_sac_admin,
12
- try_send, validate_packet,
11
+ rate_limit_capacity, rate_limit_in_flight, scan_packet_sent_event, send, set_rate_limit, set_rate_limit_with_mode,
12
+ transfer_sac_admin, try_send, validate_packet,
13
13
  },
14
14
  };
15
15
  use soroban_sdk::{testutils::Address as _, token::TokenClient, Address};
@@ -36,7 +36,7 @@ fn test_send_without_rate_limit() {
36
36
 
37
37
  let to = address_to_peer_bytes32(&receiver);
38
38
  let send_param = create_send_param(&env, chain_b.eid, 50_000_000, 0, &to);
39
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
39
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
40
40
  let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
41
41
 
42
42
  send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
@@ -76,7 +76,7 @@ fn test_send_within_rate_limit() {
76
76
  // Send 5M (within limit)
77
77
  let to = address_to_peer_bytes32(&receiver);
78
78
  let send_param = create_send_param(&env, chain_b.eid, 5_000_000, 0, &to);
79
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
79
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
80
80
  let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
81
81
 
82
82
  // Check in_flight BEFORE send
@@ -122,7 +122,7 @@ fn test_send_exceeds_rate_limit() {
122
122
  // Try to send 5M (exceeds limit)
123
123
  let to = address_to_peer_bytes32(&receiver);
124
124
  let send_param = create_send_param(&env, chain_b.eid, 5_000_000, 0, &to);
125
- let (_, _, oft_receipt) = quote_oft(&chain_a, &send_param);
125
+ let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
126
126
  let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
127
127
 
128
128
  let success = try_send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
@@ -152,7 +152,7 @@ fn test_rate_limit_decay() {
152
152
 
153
153
  // Send 8M
154
154
  let send_param1 = create_send_param(&env, chain_b.eid, 8_000_000, 0, &to);
155
- let (_, _, oft_receipt1) = quote_oft(&chain_a, &send_param1);
155
+ let (_, _, oft_receipt1) = quote_oft(&chain_a, &sender, &send_param1);
156
156
  let fee1 = quote_send(&env, &chain_a, &sender, &send_param1, false);
157
157
  send(&env, &chain_a, &sender, &send_param1, &fee1, &sender, &oft_receipt1);
158
158
 
@@ -174,7 +174,7 @@ fn test_rate_limit_decay() {
174
174
 
175
175
  // Now we should be able to send more
176
176
  let send_param2 = create_send_param(&env, chain_b.eid, 4_000_000, 0, &to);
177
- let (_, _, oft_receipt2) = quote_oft(&chain_a, &send_param2);
177
+ let (_, _, oft_receipt2) = quote_oft(&chain_a, &sender, &send_param2);
178
178
  let fee2 = quote_send(&env, &chain_a, &sender, &send_param2, false);
179
179
  send(&env, &chain_a, &sender, &send_param2, &fee2, &sender, &oft_receipt2);
180
180
 
@@ -184,3 +184,139 @@ fn test_rate_limit_decay() {
184
184
  let packet2 = decode_packet(&env, &packet_event2.0);
185
185
  lz_receive(&env, &chain_b, &executor, &packet2, &receiver, 0);
186
186
  }
187
+
188
+ /// Test gross mode: round-trip shows gross mode doesn't release outbound capacity
189
+ #[test]
190
+ fn test_gross_mode_does_not_release() {
191
+ let TestSetup { env, chain_a, chain_b } = setup();
192
+ wire_endpoint(&env, &[&chain_a, &chain_b]);
193
+ wire_oft(&env, &[&chain_a, &chain_b]);
194
+
195
+ let sender_a = Address::generate(&env);
196
+ let sender_b = Address::generate(&env);
197
+ let receiver_b = create_recipient_address(&env);
198
+ let receiver_a = create_recipient_address(&env);
199
+ let executor = Address::generate(&env);
200
+
201
+ // Setup tokens for both chains
202
+ mint_to(&env, &chain_a.owner, &chain_a.oft_token, &sender_a, 100_000_000);
203
+ mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender_a, 10_000_000_000);
204
+ mint_to(&env, &chain_b.owner, &chain_b.oft_token, &sender_b, 100_000_000);
205
+ mint_to(&env, &chain_b.owner, &chain_b.native_token, &sender_b, 10_000_000_000);
206
+ transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
207
+ transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
208
+
209
+ // Set Gross mode rate limit on chain_a outbound: 10M per 3600 seconds
210
+ set_rate_limit_with_mode(&env, &chain_a, &Direction::Outbound, chain_b.eid, 10_000_000, 3600, Mode::Gross);
211
+
212
+ // Step 1: Send 8M from chain_a to chain_b
213
+ let to_b = address_to_peer_bytes32(&receiver_b);
214
+ let send_param_1 = create_send_param(&env, chain_b.eid, 8_000_000, 0, &to_b);
215
+ let (_, _, oft_receipt_1) = quote_oft(&chain_a, &sender_a, &send_param_1);
216
+ let fee_1 = quote_send(&env, &chain_a, &sender_a, &send_param_1, false);
217
+ send(&env, &chain_a, &sender_a, &send_param_1, &fee_1, &sender_a, &oft_receipt_1);
218
+
219
+ let packet_event_1 = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
220
+ validate_packet(&env, &chain_b, &packet_event_1);
221
+ let packet_1 = decode_packet(&env, &packet_event_1.0);
222
+
223
+ // chain_a outbound should have 8M in-flight
224
+ let in_flight_after_send = rate_limit_in_flight(&chain_a, &Direction::Outbound, chain_b.eid);
225
+ assert_eq!(in_flight_after_send, oft_receipt_1.amount_received_ld);
226
+ assert_eq!(rate_limit_capacity(&chain_a, &Direction::Outbound, chain_b.eid), 10_000_000 - in_flight_after_send);
227
+
228
+ // Step 2: Receive on chain_b and send 6M back to chain_a
229
+ lz_receive(&env, &chain_b, &executor, &packet_1, &receiver_b, 0);
230
+
231
+ let to_a = address_to_peer_bytes32(&receiver_a);
232
+ let send_param_2 = create_send_param(&env, chain_a.eid, 6_000_000, 0, &to_a);
233
+ let (_, _, oft_receipt_2) = quote_oft(&chain_b, &sender_b, &send_param_2);
234
+ let fee_2 = quote_send(&env, &chain_b, &sender_b, &send_param_2, false);
235
+ send(&env, &chain_b, &sender_b, &send_param_2, &fee_2, &sender_b, &oft_receipt_2);
236
+
237
+ let packet_event_2 = scan_packet_sent_event(&env, &chain_b.endpoint.address).unwrap();
238
+ validate_packet(&env, &chain_a, &packet_event_2);
239
+ let packet_2 = decode_packet(&env, &packet_event_2.0);
240
+
241
+ // Step 3: Receive back on chain_a - this calls __release_rate_limit_capacity for outbound
242
+ lz_receive(&env, &chain_a, &executor, &packet_2, &receiver_a, 0);
243
+
244
+ // In Gross mode, receiving back should NOT release the outbound capacity
245
+ let in_flight_after_return = rate_limit_in_flight(&chain_a, &Direction::Outbound, chain_b.eid);
246
+ assert_eq!(
247
+ in_flight_after_return, in_flight_after_send,
248
+ "Gross mode: outbound in-flight should not decrease when receiving"
249
+ );
250
+
251
+ // Should only have ~2M capacity left, NOT 8M (if it were Net mode)
252
+ let capacity_after_return = rate_limit_capacity(&chain_a, &Direction::Outbound, chain_b.eid);
253
+ assert!(capacity_after_return < 3_000_000, "Gross mode: capacity should remain low");
254
+ }
255
+
256
+ /// Test net mode (default): round-trip shows net mode releases outbound capacity
257
+ #[test]
258
+ fn test_net_mode_does_release() {
259
+ let TestSetup { env, chain_a, chain_b } = setup();
260
+ wire_endpoint(&env, &[&chain_a, &chain_b]);
261
+ wire_oft(&env, &[&chain_a, &chain_b]);
262
+
263
+ let sender_a = Address::generate(&env);
264
+ let sender_b = Address::generate(&env);
265
+ let receiver_b = create_recipient_address(&env);
266
+ let receiver_a = create_recipient_address(&env);
267
+ let executor = Address::generate(&env);
268
+
269
+ // Setup tokens for both chains
270
+ mint_to(&env, &chain_a.owner, &chain_a.oft_token, &sender_a, 100_000_000);
271
+ mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender_a, 10_000_000_000);
272
+ mint_to(&env, &chain_b.owner, &chain_b.oft_token, &sender_b, 100_000_000);
273
+ mint_to(&env, &chain_b.owner, &chain_b.native_token, &sender_b, 10_000_000_000);
274
+ transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
275
+ transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
276
+
277
+ // Set Net mode rate limit on chain_a outbound: 10M per 3600 seconds
278
+ set_rate_limit_with_mode(&env, &chain_a, &Direction::Outbound, chain_b.eid, 10_000_000, 3600, Mode::Net);
279
+
280
+ // Step 1: Send 8M from chain_a to chain_b
281
+ let to_b = address_to_peer_bytes32(&receiver_b);
282
+ let send_param_1 = create_send_param(&env, chain_b.eid, 8_000_000, 0, &to_b);
283
+ let (_, _, oft_receipt_1) = quote_oft(&chain_a, &sender_a, &send_param_1);
284
+ let fee_1 = quote_send(&env, &chain_a, &sender_a, &send_param_1, false);
285
+ send(&env, &chain_a, &sender_a, &send_param_1, &fee_1, &sender_a, &oft_receipt_1);
286
+
287
+ let packet_event_1 = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
288
+ validate_packet(&env, &chain_b, &packet_event_1);
289
+ let packet_1 = decode_packet(&env, &packet_event_1.0);
290
+
291
+ // chain_a outbound should have 8M in-flight
292
+ let in_flight_after_send = rate_limit_in_flight(&chain_a, &Direction::Outbound, chain_b.eid);
293
+ assert_eq!(in_flight_after_send, oft_receipt_1.amount_received_ld);
294
+ assert_eq!(rate_limit_capacity(&chain_a, &Direction::Outbound, chain_b.eid), 10_000_000 - in_flight_after_send);
295
+
296
+ // Step 2: Receive on chain_b and send 6M back to chain_a
297
+ lz_receive(&env, &chain_b, &executor, &packet_1, &receiver_b, 0);
298
+
299
+ let to_a = address_to_peer_bytes32(&receiver_a);
300
+ let send_param_2 = create_send_param(&env, chain_a.eid, 6_000_000, 0, &to_a);
301
+ let (_, _, oft_receipt_2) = quote_oft(&chain_b, &sender_b, &send_param_2);
302
+ let fee_2 = quote_send(&env, &chain_b, &sender_b, &send_param_2, false);
303
+ send(&env, &chain_b, &sender_b, &send_param_2, &fee_2, &sender_b, &oft_receipt_2);
304
+
305
+ let packet_event_2 = scan_packet_sent_event(&env, &chain_b.endpoint.address).unwrap();
306
+ validate_packet(&env, &chain_a, &packet_event_2);
307
+ let packet_2 = decode_packet(&env, &packet_event_2.0);
308
+
309
+ // Step 3: Receive back on chain_a - this calls __release_rate_limit_capacity for outbound
310
+ lz_receive(&env, &chain_a, &executor, &packet_2, &receiver_a, 0);
311
+
312
+ // In Net mode, receiving back SHOULD release the outbound capacity
313
+ let in_flight_after_return = rate_limit_in_flight(&chain_a, &Direction::Outbound, chain_b.eid);
314
+ assert!(
315
+ in_flight_after_return < in_flight_after_send,
316
+ "Net mode: outbound in-flight should decrease when receiving"
317
+ );
318
+
319
+ // Should have much more capacity now (8M sent - 6M received back = ~2M net)
320
+ let capacity_after_return = rate_limit_capacity(&chain_a, &Direction::Outbound, chain_b.eid);
321
+ assert!(capacity_after_return > 7_000_000, "Net mode: capacity should increase after receiving");
322
+ }
@@ -82,8 +82,10 @@ fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
82
82
  let sml_address = env.register(SimpleMessageLib, (&owner, &endpoint_address, &fee_recipient));
83
83
  let delegate: Option<Address> = Some(owner.clone());
84
84
  let shared_decimals: u32 = 6; // Default shared decimals
85
- let mode = OftType::MintBurn;
86
- let oft_address = env.register(OFT, (&oft_token, &owner, &endpoint_address, &delegate, &shared_decimals, &mode));
85
+ // Both chains use MintBurn — the SAC itself implements mint/burn.
86
+ // This exercises the MintBurnableClient code path.
87
+ let mode = OftType::MintBurn(oft_token.clone());
88
+ let oft_address = env.register(OFT, (&oft_token, &shared_decimals, &mode, &owner, &endpoint_address, &delegate));
87
89
 
88
90
  let endpoint = EndpointV2Client::new(env, &endpoint_address);
89
91
  let sml = SimpleMessageLibClient::new(env, &sml_address);
@@ -1,10 +1,10 @@
1
1
  //! Utility functions for OFT-STD integration tests.
2
2
 
3
- use crate::extensions::rate_limiter::{Direction, RateLimitConfig};
3
+ use crate::extensions::rate_limiter::{Direction, Mode, RateLimitConfig};
4
4
  use crate::integration_tests::setup::{decode_packet, ChainSetup};
5
5
  use endpoint_v2::{MessagingFee, Origin, OutboundPacket};
6
6
  use message_lib_common::packet_codec_v1;
7
- use oft_core::types::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam};
7
+ use oft_core::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam};
8
8
  use soroban_sdk::{
9
9
  address_payload::AddressPayload,
10
10
  testutils::{Events, Ledger, MockAuth, MockAuthInvoke},
@@ -38,8 +38,8 @@ pub fn create_recipient_address(env: &Env) -> Address {
38
38
  // OFT Core Operations
39
39
  // ============================================================================
40
40
 
41
- pub fn quote_oft(chain: &ChainSetup<'_>, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
42
- chain.oft.quote_oft(send_param)
41
+ pub fn quote_oft(chain: &ChainSetup<'_>, from: &Address, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
42
+ chain.oft.quote_oft(from, send_param)
43
43
  }
44
44
 
45
45
  pub fn quote_send(
@@ -351,32 +351,34 @@ pub fn is_paused(chain: &ChainSetup<'_>) -> bool {
351
351
  // ============================================================================
352
352
 
353
353
  pub fn set_fee_deposit_address(env: &Env, chain: &ChainSetup<'_>, deposit_address: &Address) {
354
+ let deposit_address_opt = Some(deposit_address.clone());
354
355
  env.mock_auths(&[MockAuth {
355
356
  address: &chain.owner,
356
357
  invoke: &MockAuthInvoke {
357
358
  contract: &chain.oft.address,
358
359
  fn_name: "set_fee_deposit_address",
359
- args: (deposit_address,).into_val(env),
360
+ args: (&deposit_address_opt,).into_val(env),
360
361
  sub_invokes: &[],
361
362
  },
362
363
  }]);
363
- chain.oft.set_fee_deposit_address(deposit_address);
364
+ chain.oft.set_fee_deposit_address(&deposit_address_opt);
364
365
  }
365
366
 
366
- pub fn set_default_fee_bps(env: &Env, chain: &ChainSetup<'_>, fee_bps: u64) {
367
+ pub fn set_default_fee_bps(env: &Env, chain: &ChainSetup<'_>, fee_bps: u32) {
368
+ let fee_bps_opt = Some(fee_bps);
367
369
  env.mock_auths(&[MockAuth {
368
370
  address: &chain.owner,
369
371
  invoke: &MockAuthInvoke {
370
372
  contract: &chain.oft.address,
371
373
  fn_name: "set_default_fee_bps",
372
- args: (&fee_bps,).into_val(env),
374
+ args: (&fee_bps_opt,).into_val(env),
373
375
  sub_invokes: &[],
374
376
  },
375
377
  }]);
376
- chain.oft.set_default_fee_bps(&fee_bps);
378
+ chain.oft.set_default_fee_bps(&fee_bps_opt);
377
379
  }
378
380
 
379
- pub fn set_fee_bps(env: &Env, chain: &ChainSetup<'_>, dst_eid: u32, fee_bps: u64) {
381
+ pub fn set_fee_bps(env: &Env, chain: &ChainSetup<'_>, dst_eid: u32, fee_bps: u32) {
380
382
  let fee_bps_opt = Some(fee_bps);
381
383
  env.mock_auths(&[MockAuth {
382
384
  address: &chain.owner,
@@ -402,7 +404,19 @@ pub fn set_rate_limit(
402
404
  limit: i128,
403
405
  window_seconds: u64,
404
406
  ) {
405
- let config = Some(RateLimitConfig { limit, window_seconds });
407
+ set_rate_limit_with_mode(env, chain, direction, dst_eid, limit, window_seconds, Mode::Net);
408
+ }
409
+
410
+ pub fn set_rate_limit_with_mode(
411
+ env: &Env,
412
+ chain: &ChainSetup<'_>,
413
+ direction: &Direction,
414
+ dst_eid: u32,
415
+ limit: i128,
416
+ window_seconds: u64,
417
+ mode: Mode,
418
+ ) {
419
+ let config = Some(RateLimitConfig { limit, window_seconds, mode });
406
420
  env.mock_auths(&[MockAuth {
407
421
  address: &chain.owner,
408
422
  invoke: &MockAuthInvoke {