@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
@@ -0,0 +1,257 @@
1
+ //! update_limit_config Integration Tests
2
+
3
+ use super::test_helper::{
4
+ mock_oft_mint_auth, mock_set_mint_whitelist_auth, mock_set_supply_controller_auth, mock_update_limit_config_auth,
5
+ };
6
+ use crate::extensions::supply_control::SupplyControlClient;
7
+ use crate::extensions::supply_control::{LimitConfig, LimitConfigUpdated, SupplyControlError, SupplyControllerConfig};
8
+ use crate::tests::test_helper::TestSetup;
9
+ use soroban_sdk::Vec;
10
+ use utils::testing_utils::assert_eq_event;
11
+
12
+ #[test]
13
+ fn test_update_limit_config() {
14
+ let setup = TestSetup::new().build();
15
+ let controller = setup.generate_address();
16
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
17
+
18
+ let config = SupplyControllerConfig {
19
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 10 },
20
+ allow_any_mint_burn: true,
21
+ whitelist_addresses: Vec::new(&setup.env),
22
+ };
23
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
24
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
25
+
26
+ let new_limit = LimitConfig { limit_capacity: 5_000, refill_per_second: 50 };
27
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &controller, &new_limit);
28
+ sc_client.update_limit_config(&setup.sc_manager, &controller, &new_limit);
29
+
30
+ // Verify event
31
+ let expected = LimitConfigUpdated {
32
+ supply_controller: controller.clone(),
33
+ new_limit_config: new_limit.clone(),
34
+ old_limit_config: config.limit_config,
35
+ };
36
+ assert_eq_event(&setup.env, &setup.sac_manager, expected);
37
+
38
+ // Verify config was updated
39
+ let stored = sc_client.get_supply_controller_config(&controller).unwrap();
40
+ assert_eq!(stored.limit_config.limit_capacity, 5_000);
41
+ assert_eq!(stored.limit_config.refill_per_second, 50);
42
+ }
43
+
44
+ #[test]
45
+ fn test_update_limit_config_preserves_rate_limit_state() {
46
+ let setup = TestSetup::new().with_manager_as_sac_admin().with_supply_control_enabled().build();
47
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
48
+
49
+ let config = SupplyControllerConfig {
50
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 1 },
51
+ allow_any_mint_burn: true,
52
+ whitelist_addresses: Vec::new(&setup.env),
53
+ };
54
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &setup.oft, &Some(config.clone()));
55
+ sc_client.set_supply_controller(&setup.sc_manager, &setup.oft, &Some(config.clone()));
56
+
57
+ // Mint some tokens to consume rate limit
58
+ let recipient = setup.generate_address();
59
+ mock_oft_mint_auth(&setup, &recipient, 400_i128);
60
+ setup.sac_manager_client.mint(&recipient, &400);
61
+ assert_eq!(sc_client.get_remaining_mint_amount(&setup.oft), 600);
62
+
63
+ // Update limit config (should NOT reset remaining amount)
64
+ let new_limit = LimitConfig { limit_capacity: 2_000, refill_per_second: 1 };
65
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &setup.oft, &new_limit);
66
+ sc_client.update_limit_config(&setup.sc_manager, &setup.oft, &new_limit);
67
+
68
+ // Remaining amount should still be 600 (not reset to 2000)
69
+ assert_eq!(sc_client.get_remaining_mint_amount(&setup.oft), 600);
70
+ }
71
+
72
+ #[test]
73
+ fn test_update_limit_config_fails_with_invalid_config() {
74
+ let setup = TestSetup::new().build();
75
+ let controller = setup.generate_address();
76
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
77
+
78
+ let config = SupplyControllerConfig {
79
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 10 },
80
+ allow_any_mint_burn: true,
81
+ whitelist_addresses: Vec::new(&setup.env),
82
+ };
83
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
84
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
85
+
86
+ let invalid_limit = LimitConfig { limit_capacity: -100, refill_per_second: 10 };
87
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &controller, &invalid_limit);
88
+ let result = sc_client.try_update_limit_config(&setup.sc_manager, &controller, &invalid_limit);
89
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::InvalidConfig.into());
90
+
91
+ // Verify config remains unchanged after failed update.
92
+ let stored = sc_client.get_supply_controller_config(&controller).unwrap();
93
+ assert_eq!(stored.limit_config, config.limit_config);
94
+ }
95
+
96
+ #[test]
97
+ fn test_update_limit_config_fails_with_negative_refill_per_second() {
98
+ let setup = TestSetup::new().build();
99
+ let controller = setup.generate_address();
100
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
101
+
102
+ let config = SupplyControllerConfig {
103
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 10 },
104
+ allow_any_mint_burn: true,
105
+ whitelist_addresses: Vec::new(&setup.env),
106
+ };
107
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
108
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
109
+
110
+ let invalid_limit = LimitConfig { limit_capacity: 1_000, refill_per_second: -1 };
111
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &controller, &invalid_limit);
112
+ let result = sc_client.try_update_limit_config(&setup.sc_manager, &controller, &invalid_limit);
113
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::InvalidConfig.into());
114
+
115
+ // Verify config remains unchanged after failed update.
116
+ let stored = sc_client.get_supply_controller_config(&controller).unwrap();
117
+ assert_eq!(stored.limit_config, config.limit_config);
118
+ }
119
+
120
+ #[test]
121
+ fn test_update_limit_config_preserves_allow_any_and_whitelist() {
122
+ let setup = TestSetup::new().build();
123
+ let controller = setup.generate_address();
124
+ let whitelisted = setup.generate_address();
125
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
126
+
127
+ let config = SupplyControllerConfig {
128
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 10 },
129
+ allow_any_mint_burn: false,
130
+ whitelist_addresses: Vec::new(&setup.env),
131
+ };
132
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
133
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
134
+
135
+ // Add whitelisted address before updating limit config
136
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &whitelisted, true);
137
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &whitelisted, &true);
138
+
139
+ let new_limit = LimitConfig { limit_capacity: 3_000, refill_per_second: 30 };
140
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &controller, &new_limit);
141
+ sc_client.update_limit_config(&setup.sc_manager, &controller, &new_limit);
142
+
143
+ let stored = sc_client.get_supply_controller_config(&controller).unwrap();
144
+ assert_eq!(stored.limit_config, new_limit);
145
+ assert_eq!(stored.allow_any_mint_burn, config.allow_any_mint_burn);
146
+ assert!(sc_client.is_address_whitelisted(&controller, &whitelisted));
147
+ }
148
+
149
+ #[test]
150
+ fn test_update_limit_config_switch_to_unlimited_and_back() {
151
+ let setup = TestSetup::new().with_manager_as_sac_admin().with_supply_control_enabled().build();
152
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
153
+
154
+ let config = SupplyControllerConfig {
155
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 1 },
156
+ allow_any_mint_burn: true,
157
+ whitelist_addresses: Vec::new(&setup.env),
158
+ };
159
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &setup.oft, &Some(config.clone()));
160
+ sc_client.set_supply_controller(&setup.sc_manager, &setup.oft, &Some(config));
161
+
162
+ let recipient = setup.generate_address();
163
+ mock_oft_mint_auth(&setup, &recipient, 400_i128);
164
+ setup.sac_manager_client.mint(&recipient, &400);
165
+ assert_eq!(sc_client.get_remaining_mint_amount(&setup.oft), 600);
166
+
167
+ let unlimited = LimitConfig { limit_capacity: 1_000, refill_per_second: 0 };
168
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &setup.oft, &unlimited);
169
+ sc_client.update_limit_config(&setup.sc_manager, &setup.oft, &unlimited);
170
+ assert_eq!(sc_client.get_remaining_mint_amount(&setup.oft), i128::MAX);
171
+
172
+ let limited_again = LimitConfig { limit_capacity: 2_000, refill_per_second: 1 };
173
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &setup.oft, &limited_again);
174
+ sc_client.update_limit_config(&setup.sc_manager, &setup.oft, &limited_again);
175
+ assert_eq!(sc_client.get_remaining_mint_amount(&setup.oft), 600);
176
+ }
177
+
178
+ #[test]
179
+ fn test_update_limit_config_event_tracks_previous_value_across_updates() {
180
+ let setup = TestSetup::new().build();
181
+ let controller = setup.generate_address();
182
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
183
+
184
+ let initial = LimitConfig { limit_capacity: 1_000, refill_per_second: 10 };
185
+ let config = SupplyControllerConfig {
186
+ limit_config: initial.clone(),
187
+ allow_any_mint_burn: true,
188
+ whitelist_addresses: Vec::new(&setup.env),
189
+ };
190
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
191
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config));
192
+
193
+ let first = LimitConfig { limit_capacity: 2_000, refill_per_second: 20 };
194
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &controller, &first);
195
+ sc_client.update_limit_config(&setup.sc_manager, &controller, &first);
196
+
197
+ let second = LimitConfig { limit_capacity: 3_000, refill_per_second: 30 };
198
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &controller, &second);
199
+ sc_client.update_limit_config(&setup.sc_manager, &controller, &second);
200
+
201
+ let expected =
202
+ LimitConfigUpdated { supply_controller: controller, new_limit_config: second, old_limit_config: first };
203
+ assert_eq_event(&setup.env, &setup.sac_manager, expected);
204
+ }
205
+
206
+ #[test]
207
+ fn test_update_limit_config_fails_if_not_supply_controller() {
208
+ let setup = TestSetup::new().build();
209
+ let non_controller = setup.generate_address();
210
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
211
+
212
+ let limit = LimitConfig { limit_capacity: 1_000, refill_per_second: 10 };
213
+ mock_update_limit_config_auth(&setup, &setup.sc_manager, &non_controller, &limit);
214
+ let result = sc_client.try_update_limit_config(&setup.sc_manager, &non_controller, &limit);
215
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::NotFound.into());
216
+ }
217
+
218
+ #[test]
219
+ fn test_update_limit_config_by_non_manager_fails() {
220
+ let setup = TestSetup::new().build();
221
+ let non_manager = setup.generate_address();
222
+ let controller = setup.generate_address();
223
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
224
+
225
+ let config = SupplyControllerConfig {
226
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 10 },
227
+ allow_any_mint_burn: true,
228
+ whitelist_addresses: Vec::new(&setup.env),
229
+ };
230
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
231
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
232
+
233
+ let new_limit = LimitConfig { limit_capacity: 5_000, refill_per_second: 50 };
234
+ mock_update_limit_config_auth(&setup, &non_manager, &controller, &new_limit);
235
+ let result = sc_client.try_update_limit_config(&non_manager, &controller, &new_limit);
236
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::Unauthorized.into());
237
+ }
238
+
239
+ #[test]
240
+ #[should_panic(expected = "Error(Auth, InvalidAction)")]
241
+ fn test_update_limit_config_without_auth() {
242
+ let setup = TestSetup::new().build();
243
+ let controller = setup.generate_address();
244
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
245
+
246
+ let config = SupplyControllerConfig {
247
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 10 },
248
+ allow_any_mint_burn: true,
249
+ whitelist_addresses: Vec::new(&setup.env),
250
+ };
251
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
252
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
253
+
254
+ // sc_manager's auth is not mocked — sender.require_auth() fails
255
+ let new_limit = LimitConfig { limit_capacity: 5_000, refill_per_second: 50 };
256
+ sc_client.update_limit_config(&setup.sc_manager, &controller, &new_limit);
257
+ }
@@ -0,0 +1,190 @@
1
+ //! Test helper utilities for SAC manager tests.
2
+ //!
3
+ //! Provides authentication mocking helpers and common setup utilities.
4
+
5
+ extern crate std;
6
+
7
+ use crate::{SacManager, SacManagerClient};
8
+ use soroban_sdk::{
9
+ testutils::{Address as _, MockAuth, MockAuthInvoke, StellarAssetContract},
10
+ token::StellarAssetClient,
11
+ Address, Env, IntoVal, Val,
12
+ };
13
+
14
+ // =========================================================================
15
+ // TestSetup Builder
16
+ // =========================================================================
17
+
18
+ /// Builder for creating test setups with chainable configuration.
19
+ ///
20
+ /// # Example
21
+ /// ```ignore
22
+ /// let setup = TestSetup::new()
23
+ /// .with_manager_as_sac_admin()
24
+ /// .build();
25
+ /// ```
26
+ pub struct TestSetupBuilder {
27
+ manager_as_sac_admin: bool,
28
+ redistribution_enabled: bool,
29
+ supply_control_enabled: bool,
30
+ skip_oft_setup: bool,
31
+ }
32
+
33
+ impl TestSetupBuilder {
34
+ fn new() -> Self {
35
+ Self {
36
+ manager_as_sac_admin: false,
37
+ redistribution_enabled: false,
38
+ supply_control_enabled: false,
39
+ skip_oft_setup: false,
40
+ }
41
+ }
42
+
43
+ /// Set the SacManager as SAC admin during setup.
44
+ pub fn with_manager_as_sac_admin(mut self) -> Self {
45
+ self.manager_as_sac_admin = true;
46
+ self
47
+ }
48
+
49
+ /// Enable redistribution at construction time.
50
+ pub fn with_redistribution_enabled(mut self) -> Self {
51
+ self.redistribution_enabled = true;
52
+ self
53
+ }
54
+
55
+ /// Enable supply control at construction time.
56
+ pub fn with_supply_control_enabled(mut self) -> Self {
57
+ self.supply_control_enabled = true;
58
+ self
59
+ }
60
+
61
+ /// Skip setting the OFT address during setup.
62
+ /// Use this to test `set_oft_address` auth or the once-only guard.
63
+ pub fn without_oft(mut self) -> Self {
64
+ self.skip_oft_setup = true;
65
+ self
66
+ }
67
+
68
+ /// Build the TestSetup with the configured options.
69
+ pub fn build<'a>(self) -> TestSetup<'a> {
70
+ let env = Env::default();
71
+
72
+ let owner = Address::generate(&env);
73
+ let oft = Address::generate(&env);
74
+ let sc_manager = Address::generate(&env);
75
+ let sac_contract = env.register_stellar_asset_contract_v2(owner.clone());
76
+ let sac = sac_contract.address();
77
+
78
+ let sac_manager =
79
+ env.register(SacManager, (&sac, &owner, self.redistribution_enabled, self.supply_control_enabled));
80
+ let sac_manager_client = SacManagerClient::new(&env, &sac_manager);
81
+ let sac_client = StellarAssetClient::new(&env, &sac);
82
+
83
+ if !self.skip_oft_setup {
84
+ env.mock_auths(&[MockAuth {
85
+ address: &owner,
86
+ invoke: &MockAuthInvoke {
87
+ contract: &sac_manager,
88
+ fn_name: "set_oft_address",
89
+ args: (&oft,).into_val(&env),
90
+ sub_invokes: &[],
91
+ },
92
+ }]);
93
+ sac_manager_client.set_oft_address(&oft);
94
+ }
95
+
96
+ if self.manager_as_sac_admin {
97
+ env.mock_auths(&[MockAuth {
98
+ address: &owner,
99
+ invoke: &MockAuthInvoke {
100
+ contract: &sac,
101
+ fn_name: "set_admin",
102
+ args: (&sac_manager,).into_val(&env),
103
+ sub_invokes: &[],
104
+ },
105
+ }]);
106
+ sac_client.set_admin(&sac_manager);
107
+ }
108
+
109
+ // Set up supply controller manager (owner grants the role)
110
+ env.mock_auths(&[MockAuth {
111
+ address: &owner,
112
+ invoke: &MockAuthInvoke {
113
+ contract: &sac_manager,
114
+ fn_name: "set_supply_controller_manager",
115
+ args: (&sc_manager, true).into_val(&env),
116
+ sub_invokes: &[],
117
+ },
118
+ }]);
119
+ sac_manager_client.set_supply_controller_manager(&sc_manager, &true);
120
+
121
+ // Clear mock auths so test starts with clean auth state
122
+ env.mock_auths(&[]);
123
+
124
+ TestSetup { env, owner, oft, sc_manager, sac, sac_contract, sac_manager, sac_manager_client, sac_client }
125
+ }
126
+ }
127
+
128
+ // =========================================================================
129
+ // TestSetup
130
+ // =========================================================================
131
+
132
+ /// Common test setup that creates a SAC and SacManager.
133
+ pub struct TestSetup<'a> {
134
+ pub env: Env,
135
+ pub owner: Address,
136
+ pub oft: Address,
137
+ pub sc_manager: Address,
138
+ pub sac: Address,
139
+ pub sac_contract: StellarAssetContract,
140
+ pub sac_manager: Address,
141
+ pub sac_manager_client: SacManagerClient<'a>,
142
+ pub sac_client: StellarAssetClient<'a>,
143
+ }
144
+
145
+ impl TestSetup<'_> {
146
+ /// Start building a new test setup.
147
+ pub fn new() -> TestSetupBuilder {
148
+ TestSetupBuilder::new()
149
+ }
150
+
151
+ /// Generate a new random address in this test environment.
152
+ pub fn generate_address(&self) -> Address {
153
+ Address::generate(&self.env)
154
+ }
155
+ }
156
+
157
+ // =========================================================================
158
+ // Auth Helpers
159
+ // =========================================================================
160
+
161
+ /// Test helper to mock a single contract invocation auth.
162
+ ///
163
+ /// This keeps test files from repeating `env.mock_auths(&[MockAuth { ... }])` blocks.
164
+ pub fn mock_auth<A: IntoVal<Env, soroban_sdk::Vec<Val>>>(
165
+ env: &Env,
166
+ contract_id: &Address,
167
+ address: &Address,
168
+ fn_name: &'static str,
169
+ args: A,
170
+ ) {
171
+ env.mock_auths(&[MockAuth {
172
+ address,
173
+ invoke: &MockAuthInvoke { contract: contract_id, args: args.into_val(env), fn_name, sub_invokes: &[] },
174
+ }]);
175
+ }
176
+
177
+ /// Mock auth for `set_supply_controller`.
178
+ pub fn mock_set_supply_controller_auth(
179
+ setup: &TestSetup,
180
+ sender: &Address,
181
+ controller: &Address,
182
+ config: &Option<crate::extensions::supply_control::SupplyControllerConfig>,
183
+ ) {
184
+ mock_auth(&setup.env, &setup.sac_manager, sender, "set_supply_controller", (sender, controller, config.clone()));
185
+ }
186
+
187
+ /// Mock auth for OFT-originated `mint`.
188
+ pub fn mock_oft_mint_auth(setup: &TestSetup, recipient: &Address, amount: i128) {
189
+ mock_auth(&setup.env, &setup.sac_manager, &setup.oft, "mint", (recipient, amount));
190
+ }
@@ -20,7 +20,7 @@
20
20
  //! ```
21
21
 
22
22
  use soroban_sdk::{contract, contractimpl, xdr::ToXdr, Address, Bytes, BytesN, Env};
23
- use utils::upgradeable::UpgradeableClient;
23
+ use utils::{auth::AuthClient, upgradeable::UpgradeableClient};
24
24
 
25
25
  /// Upgrader contract for managing upgrades of other contracts.
26
26
  ///
@@ -59,6 +59,7 @@ impl Upgrader {
59
59
  /// upgrader.upgrade_and_migrate(&contract_addr, &wasm_hash, &migration_data);
60
60
  /// ```
61
61
  pub fn upgrade_and_migrate(env: &Env, contract_address: &Address, wasm_hash: &BytesN<32>, migration_data: &Bytes) {
62
+ AuthClient::new(env, contract_address).authorizer().require_auth();
62
63
  let client = UpgradeableClient::new(env, contract_address);
63
64
  client.upgrade(wasm_hash);
64
65
  client.migrate(migration_data);
@@ -47,7 +47,6 @@ pub enum BytesExtError {
47
47
  pub enum UpgradeableError {
48
48
  InvalidMigrationData = 1050,
49
49
  MigrationNotAllowed,
50
- UpgradesFrozen,
51
50
  }
52
51
 
53
52
  /// MultiSigError: 1060-1069
@@ -528,69 +528,3 @@ fn test_cannot_migrate_twice_without_upgrade() {
528
528
  assert_eq!(result.err().unwrap().ok().unwrap(), UpgradeableError::MigrationNotAllowed.into());
529
529
  }
530
530
 
531
- // ============================================
532
- // Freeze Feature Tests
533
- // ============================================
534
-
535
- #[test]
536
- fn test_freeze_success() {
537
- let env = Env::default();
538
- env.mock_all_auths();
539
- let contract_id = env.register(DummyContract, ());
540
- let client = DummyContractClient::new(&env, &contract_id);
541
-
542
- // Initially, contract should not be frozen
543
- assert_eq!(client.is_frozen(), false);
544
-
545
- // Freeze the contract
546
- client.freeze();
547
-
548
- // Verify the contract is now frozen
549
- assert_eq!(client.is_frozen(), true);
550
- }
551
-
552
- #[test]
553
- #[should_panic(expected = "Error(Contract, #1052)")] // UpgradesFrozen
554
- fn test_upgrade_fails_when_frozen() {
555
- let env = Env::default();
556
- env.mock_all_auths();
557
- let contract_id = env.register(DummyContract, ());
558
- let client = DummyContractClient::new(&env, &contract_id);
559
-
560
- // Upload valid contract WASM
561
- let wasm_hash = env.deployer().upload_contract_wasm(Bytes::from_slice(&env, TEST_WASM));
562
-
563
- // Freeze the contract first
564
- client.freeze();
565
-
566
- // Try to upgrade - should panic with UpgradesFrozen
567
- client.upgrade(&wasm_hash);
568
- }
569
-
570
- #[test]
571
- #[should_panic(expected = "Error(Contract, #1052)")] // UpgradesFrozen
572
- fn test_freeze_multiple_times() {
573
- let env = Env::default();
574
- env.mock_all_auths();
575
- let contract_id = env.register(DummyContract, ());
576
- let client = DummyContractClient::new(&env, &contract_id);
577
-
578
- // First freeze should succeed
579
- client.freeze();
580
- assert_eq!(client.is_frozen(), true);
581
-
582
- // Second freeze should panic with UpgradesFrozen
583
- client.freeze();
584
- }
585
-
586
- #[test]
587
- #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
588
- fn test_freeze_requires_auth() {
589
- let env = Env::default();
590
- // Note: NOT calling mock_all_auths() - auth will fail
591
- let contract_id = env.register(DummyContract, ());
592
- let client = DummyContractClient::new(&env, &contract_id);
593
-
594
- // Try to freeze without auth - should panic
595
- client.freeze();
596
- }
@@ -15,7 +15,6 @@ pub trait Upgradeable: UpgradeableInternal + Auth {
15
15
  /// Sets a migration flag that must be cleared by calling `migrate`.
16
16
  #[only_auth]
17
17
  fn upgrade(env: &soroban_sdk::Env, new_wasm_hash: &soroban_sdk::BytesN<32>) {
18
- assert_with_error!(env, !Self::is_frozen(env), UpgradeableError::UpgradesFrozen);
19
18
  UpgradeableStorage::set_migrating(env, &true);
20
19
  env.deployer().update_current_contract_wasm(new_wasm_hash.clone());
21
20
  }
@@ -35,18 +34,6 @@ pub trait Upgradeable: UpgradeableInternal + Auth {
35
34
  // Clear the migration flag after migration is successful
36
35
  UpgradeableStorage::set_migrating(env, &false);
37
36
  }
38
-
39
- /// Permanently freezes the contract, preventing any future upgrades. Irreversible.
40
- #[only_auth]
41
- fn freeze(env: &soroban_sdk::Env) {
42
- assert_with_error!(env, !Self::is_frozen(env), UpgradeableError::UpgradesFrozen);
43
- UpgradeableStorage::set_frozen(env, &true);
44
- }
45
-
46
- /// Returns whether the contract is frozen (upgrades disabled).
47
- fn is_frozen(env: &soroban_sdk::Env) -> bool {
48
- UpgradeableStorage::frozen(env)
49
- }
50
37
  }
51
38
 
52
39
  /// Trait for defining contract-specific migration logic.
@@ -66,11 +53,6 @@ pub trait UpgradeableInternal {
66
53
  /// Storage for upgrade state.
67
54
  #[storage]
68
55
  pub enum UpgradeableStorage {
69
- /// Whether upgrades are permanently disabled.
70
- #[instance(bool)]
71
- #[default(false)]
72
- Frozen,
73
-
74
56
  /// Whether a migration is pending.
75
57
  #[instance(bool)]
76
58
  #[default(false)]
@@ -13,8 +13,8 @@ use message_lib_common::interfaces::ILayerZeroDVN;
13
13
  use soroban_sdk::{xdr::ToXdr, Address, Bytes, BytesN, Env, Vec};
14
14
  use utils::{buffer_writer::BufferWriter, multisig, option_ext::OptionExt};
15
15
  use worker::{
16
- assert_acl, assert_not_paused, assert_supported_message_lib, errors::WorkerError, init_worker, require_admin_auth,
17
- set_admin_by_admin, Worker,
16
+ assert_acl, assert_not_paused, assert_supported_message_lib, init_worker, require_admin_auth, set_admin_by_admin,
17
+ Worker, WorkerError,
18
18
  };
19
19
 
20
20
  /// LayerZero DVN contract.
@@ -1,5 +1,5 @@
1
1
  use message_lib_common::interfaces::ILayerZeroDVN;
2
- use soroban_sdk::{contractclient, contracttype, Address, BytesN, Env, Symbol, Val, Vec};
2
+ use soroban_sdk::{auth::CustomAccountInterface, contractclient, contracttype, Address, BytesN, Env, Symbol, Val, Vec};
3
3
  use utils::multisig::MultiSig;
4
4
  use worker::Worker;
5
5
 
@@ -82,7 +82,7 @@ pub struct Call {
82
82
  /// Extends the LayerZero DVN interface with destination configuration management
83
83
  /// and multisig capabilities for secure cross-chain message verification.
84
84
  #[contractclient(name = "DVNClient")]
85
- pub trait IDVN: ILayerZeroDVN + Worker + MultiSig {
85
+ pub trait IDVN: ILayerZeroDVN + Worker + MultiSig + CustomAccountInterface {
86
86
  /// Sets the configuration for one or more destination chains.
87
87
  ///
88
88
  /// # Arguments
@@ -1,7 +1,8 @@
1
1
  #![no_std]
2
2
 
3
- mod errors;
4
3
  pub mod events;
4
+
5
+ mod errors;
5
6
  mod interfaces;
6
7
 
7
8
  pub use errors::*;
@@ -1,6 +1,8 @@
1
1
  #![no_std]
2
2
 
3
- pub mod errors;
3
+ mod errors;
4
+
5
+ pub use errors::*;
4
6
 
5
7
  cfg_if::cfg_if! {
6
8
  // Include implementation when NOT in library mode, OR when testutils is enabled (for tests)