@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,256 @@
1
+ //! Supply Controller Add/Remove & Enumeration Edge-Case Tests
2
+ //!
3
+ //! Focuses on add/remove controller mechanics, re-adding after
4
+ //! removal, removing all controllers, and verifying initial rate-limit state.
5
+
6
+ use super::test_helper::mock_set_supply_controller_auth;
7
+ use crate::extensions::supply_control::{LimitConfig, SupplyControlClient, SupplyControlError, SupplyControllerConfig};
8
+ use crate::tests::test_helper::TestSetup;
9
+ use soroban_sdk::{Env, Vec};
10
+
11
+ // =========================================================================
12
+ // Helpers
13
+ // =========================================================================
14
+
15
+ fn default_config(env: &Env) -> SupplyControllerConfig {
16
+ SupplyControllerConfig {
17
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 10 },
18
+ allow_any_mint_burn: true,
19
+ whitelist_addresses: Vec::new(env),
20
+ }
21
+ }
22
+
23
+ fn add(setup: &TestSetup, sc_client: &SupplyControlClient, controller: &soroban_sdk::Address) {
24
+ let config = default_config(&setup.env);
25
+ mock_set_supply_controller_auth(setup, &setup.sc_manager, controller, &Some(config.clone()));
26
+ sc_client.set_supply_controller(&setup.sc_manager, controller, &Some(config));
27
+ }
28
+
29
+ fn remove(setup: &TestSetup, sc_client: &SupplyControlClient, controller: &soroban_sdk::Address) {
30
+ mock_set_supply_controller_auth(setup, &setup.sc_manager, controller, &None);
31
+ sc_client.set_supply_controller(&setup.sc_manager, controller, &None);
32
+ }
33
+
34
+ // =========================================================================
35
+ // Initial Rate-Limit State
36
+ // =========================================================================
37
+
38
+ #[test]
39
+ fn test_add_supply_controller_initial_rate_limit_state() {
40
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
41
+ let controller = setup.generate_address();
42
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
43
+
44
+ let config = SupplyControllerConfig {
45
+ limit_config: LimitConfig { limit_capacity: 5_000, refill_per_second: 50 },
46
+ allow_any_mint_burn: false,
47
+ whitelist_addresses: Vec::new(&setup.env),
48
+ };
49
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
50
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
51
+
52
+ // remaining_mint_amount should equal limit_capacity at t=0
53
+ let remaining = sc_client.get_remaining_mint_amount(&controller);
54
+ assert_eq!(remaining, 5_000);
55
+
56
+ // Config should match what we set
57
+ let stored = sc_client.get_supply_controller_config(&controller).unwrap();
58
+ assert_eq!(stored.limit_config.limit_capacity, 5_000);
59
+ assert_eq!(stored.limit_config.refill_per_second, 50);
60
+ assert_eq!(stored.allow_any_mint_burn, false);
61
+ }
62
+
63
+ // =========================================================================
64
+ // Re-add After Removal
65
+ // =========================================================================
66
+
67
+ #[test]
68
+ fn test_readd_supply_controller_after_removal() {
69
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
70
+ let controller = setup.generate_address();
71
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
72
+
73
+ // Add, remove, then add again — should succeed
74
+ add(&setup, &sc_client, &controller);
75
+ assert!(sc_client.get_supply_controller_config(&controller).is_some());
76
+
77
+ remove(&setup, &sc_client, &controller);
78
+ assert!(sc_client.get_supply_controller_config(&controller).is_none());
79
+
80
+ add(&setup, &sc_client, &controller);
81
+ assert!(sc_client.get_supply_controller_config(&controller).is_some());
82
+ }
83
+
84
+ // =========================================================================
85
+ // Remove From Middle / First / Last
86
+ // =========================================================================
87
+
88
+ #[test]
89
+ fn test_remove_middle_controller() {
90
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
91
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
92
+
93
+ let c1 = setup.generate_address();
94
+ let c2 = setup.generate_address();
95
+ let c3 = setup.generate_address();
96
+
97
+ add(&setup, &sc_client, &c1);
98
+ add(&setup, &sc_client, &c2);
99
+ add(&setup, &sc_client, &c3);
100
+
101
+ // Remove the middle controller (c2).
102
+ remove(&setup, &sc_client, &c2);
103
+
104
+ let controllers = sc_client.get_supply_controllers();
105
+ assert_eq!(controllers.len(), 2);
106
+ assert!(controllers.contains(&c1));
107
+ assert!(controllers.contains(&c3));
108
+ assert!(!controllers.contains(&c2));
109
+ }
110
+
111
+ #[test]
112
+ fn test_remove_first_controller() {
113
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
114
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
115
+
116
+ let c1 = setup.generate_address();
117
+ let c2 = setup.generate_address();
118
+ let c3 = setup.generate_address();
119
+
120
+ add(&setup, &sc_client, &c1);
121
+ add(&setup, &sc_client, &c2);
122
+ add(&setup, &sc_client, &c3);
123
+
124
+ // Remove first controller (c1).
125
+ remove(&setup, &sc_client, &c1);
126
+
127
+ let controllers = sc_client.get_supply_controllers();
128
+ assert_eq!(controllers.len(), 2);
129
+ assert!(controllers.contains(&c2));
130
+ assert!(controllers.contains(&c3));
131
+ assert!(!controllers.contains(&c1));
132
+ }
133
+
134
+ #[test]
135
+ fn test_remove_last_controller() {
136
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
137
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
138
+
139
+ let c1 = setup.generate_address();
140
+ let c2 = setup.generate_address();
141
+ let c3 = setup.generate_address();
142
+
143
+ add(&setup, &sc_client, &c1);
144
+ add(&setup, &sc_client, &c2);
145
+ add(&setup, &sc_client, &c3);
146
+
147
+ // Remove last controller.
148
+ remove(&setup, &sc_client, &c3);
149
+
150
+ let controllers = sc_client.get_supply_controllers();
151
+ assert_eq!(controllers.len(), 2);
152
+ assert!(controllers.contains(&c1));
153
+ assert!(controllers.contains(&c2));
154
+ }
155
+
156
+ // =========================================================================
157
+ // Remove All Controllers
158
+ // =========================================================================
159
+
160
+ #[test]
161
+ fn test_remove_all_controllers() {
162
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
163
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
164
+
165
+ let c1 = setup.generate_address();
166
+ let c2 = setup.generate_address();
167
+
168
+ add(&setup, &sc_client, &c1);
169
+ add(&setup, &sc_client, &c2);
170
+
171
+ remove(&setup, &sc_client, &c1);
172
+ remove(&setup, &sc_client, &c2);
173
+
174
+ let controllers = sc_client.get_supply_controllers();
175
+ assert_eq!(controllers.len(), 0);
176
+ }
177
+
178
+ #[test]
179
+ fn test_remove_single_controller() {
180
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
181
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
182
+
183
+ let c1 = setup.generate_address();
184
+ add(&setup, &sc_client, &c1);
185
+
186
+ remove(&setup, &sc_client, &c1);
187
+
188
+ let controllers = sc_client.get_supply_controllers();
189
+ assert_eq!(controllers.len(), 0);
190
+ assert!(sc_client.get_supply_controller_config(&c1).is_none());
191
+ }
192
+
193
+ // =========================================================================
194
+ // Get All Controllers
195
+ // =========================================================================
196
+
197
+ #[test]
198
+ fn test_get_supply_controllers_empty() {
199
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
200
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
201
+
202
+ let controllers = sc_client.get_supply_controllers();
203
+ assert_eq!(controllers.len(), 0);
204
+ }
205
+
206
+ // =========================================================================
207
+ // Multiple Add/Remove Cycles
208
+ // =========================================================================
209
+
210
+ #[test]
211
+ fn test_multiple_add_remove_cycles() {
212
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
213
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
214
+
215
+ let c1 = setup.generate_address();
216
+ let c2 = setup.generate_address();
217
+ let c3 = setup.generate_address();
218
+
219
+ // Add all three
220
+ add(&setup, &sc_client, &c1);
221
+ add(&setup, &sc_client, &c2);
222
+ add(&setup, &sc_client, &c3);
223
+
224
+ // Remove middle, then re-add it
225
+ remove(&setup, &sc_client, &c2);
226
+ add(&setup, &sc_client, &c2);
227
+
228
+ let controllers = sc_client.get_supply_controllers();
229
+ assert_eq!(controllers.len(), 3);
230
+ assert!(controllers.contains(&c1));
231
+ assert!(controllers.contains(&c2));
232
+ assert!(controllers.contains(&c3));
233
+
234
+ // Remove first two, verify only c3 remains
235
+ remove(&setup, &sc_client, &c1);
236
+ remove(&setup, &sc_client, &c2);
237
+
238
+ let controllers = sc_client.get_supply_controllers();
239
+ assert_eq!(controllers.len(), 1);
240
+ assert!(controllers.contains(&c3));
241
+ }
242
+
243
+ #[test]
244
+ fn test_remove_already_removed_fails() {
245
+ let setup = TestSetup::new().with_manager_as_sac_admin().build();
246
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
247
+
248
+ let c1 = setup.generate_address();
249
+ add(&setup, &sc_client, &c1);
250
+ remove(&setup, &sc_client, &c1);
251
+
252
+ // Removing again should fail with NotFound
253
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &c1, &None);
254
+ let result = sc_client.try_set_supply_controller(&setup.sc_manager, &c1, &None);
255
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::NotFound.into());
256
+ }
@@ -0,0 +1,8 @@
1
+ mod enumerable_set;
2
+ mod refill;
3
+ mod set_mint_whitelist;
4
+ mod set_supply_controller;
5
+ mod set_supply_controller_manager;
6
+ mod test_helper;
7
+ mod update_allow_any_mint_burn;
8
+ mod update_limit_config;
@@ -0,0 +1,90 @@
1
+ //! refill() Unit Tests
2
+ //!
3
+ //! Unit tests for the pure `refill` helper in the supply control extension.
4
+ //! These tests do not require deploying the SacManager contract.
5
+
6
+ use crate::extensions::supply_control::rate_limit::{test::refill_for_test, LimitConfig, RateLimitState};
7
+ use crate::extensions::supply_control::SupplyControlError;
8
+
9
+ #[test]
10
+ fn test_refill_no_time_elapsed() {
11
+ let limit_config = LimitConfig { limit_capacity: 1000, refill_per_second: 10 };
12
+ let state = RateLimitState { remaining_amount: 500, last_refill_time: 100 };
13
+
14
+ // No time elapsed
15
+ let result = refill_for_test(&limit_config, &state, 100).unwrap();
16
+ assert_eq!(result, 500);
17
+ }
18
+
19
+ #[test]
20
+ fn test_refill_partial_refill() {
21
+ let limit_config = LimitConfig { limit_capacity: 1000, refill_per_second: 10 };
22
+ let state = RateLimitState { remaining_amount: 500, last_refill_time: 100 };
23
+
24
+ // 10 seconds elapsed = 100 tokens refilled
25
+ let result = refill_for_test(&limit_config, &state, 110).unwrap();
26
+ assert_eq!(result, 600);
27
+ }
28
+
29
+ #[test]
30
+ fn test_refill_capped_at_capacity() {
31
+ let limit_config = LimitConfig { limit_capacity: 1000, refill_per_second: 10 };
32
+ let state = RateLimitState { remaining_amount: 950, last_refill_time: 100 };
33
+
34
+ // 100 seconds elapsed = 1000 tokens, but capped at capacity
35
+ let result = refill_for_test(&limit_config, &state, 200).unwrap();
36
+ assert_eq!(result, 1000);
37
+ }
38
+
39
+ #[test]
40
+ fn test_refill_from_zero() {
41
+ let limit_config = LimitConfig { limit_capacity: 1000, refill_per_second: 100 };
42
+ let state = RateLimitState { remaining_amount: 0, last_refill_time: 0 };
43
+
44
+ // 5 seconds elapsed = 500 tokens
45
+ let result = refill_for_test(&limit_config, &state, 5).unwrap();
46
+ assert_eq!(result, 500);
47
+ }
48
+
49
+ #[test]
50
+ fn test_refill_with_zero_refill_rate() {
51
+ // Note: In practice, refill_per_second=0 means unlimited (checked elsewhere)
52
+ // but the refill function itself just does the math
53
+ let limit_config = LimitConfig { limit_capacity: 1000, refill_per_second: 0 };
54
+ let state = RateLimitState { remaining_amount: 500, last_refill_time: 100 };
55
+
56
+ // Any time elapsed, but no refill since rate is 0
57
+ let result = refill_for_test(&limit_config, &state, 200).unwrap();
58
+ assert_eq!(result, 500);
59
+ }
60
+
61
+ #[test]
62
+ fn test_refill_returns_capacity_on_overflow() {
63
+ // On arithmetic overflow, returns limit_capacity (aligned with EVM RateLimiter)
64
+ let limit_config = LimitConfig { limit_capacity: 5_000, refill_per_second: i128::MAX / 2 };
65
+ let state = RateLimitState { remaining_amount: i128::MAX / 2, last_refill_time: 0 };
66
+
67
+ // Multiplication overflows → returns limit_capacity
68
+ let result = refill_for_test(&limit_config, &state, 1000).unwrap();
69
+ assert_eq!(result, 5_000);
70
+ }
71
+
72
+ #[test]
73
+ fn test_refill_returns_capacity_on_add_overflow() {
74
+ // Addition overflows → returns limit_capacity
75
+ let limit_config = LimitConfig { limit_capacity: 10_000, refill_per_second: 1 };
76
+ let state = RateLimitState { remaining_amount: i128::MAX, last_refill_time: 0 };
77
+
78
+ let result = refill_for_test(&limit_config, &state, 10).unwrap();
79
+ assert_eq!(result, 10_000);
80
+ }
81
+
82
+ #[test]
83
+ fn test_refill_errors_on_old_timestamp() {
84
+ let limit_config = LimitConfig { limit_capacity: 1000, refill_per_second: 10 };
85
+ let state = RateLimitState { remaining_amount: 500, last_refill_time: 200 };
86
+
87
+ // timestamp (100) < last_refill_time (200) → should return Err
88
+ let result = refill_for_test(&limit_config, &state, 100);
89
+ assert_eq!(result.err().unwrap(), SupplyControlError::OldTimestamp.into());
90
+ }
@@ -0,0 +1,245 @@
1
+ //! set_mint_whitelist Integration Tests
2
+
3
+ use super::test_helper::{mock_set_mint_whitelist_auth, mock_set_supply_controller_auth};
4
+ use crate::extensions::supply_control::SupplyControlClient;
5
+ use crate::extensions::supply_control::{LimitConfig, MintWhitelistSet, SupplyControlError, SupplyControllerConfig};
6
+ use crate::tests::test_helper::TestSetup;
7
+ use soroban_sdk::Vec;
8
+ use utils::testing_utils::assert_eq_event;
9
+
10
+ #[test]
11
+ fn test_set_mint_whitelist_add() {
12
+ let setup = TestSetup::new().build();
13
+ let controller = setup.generate_address();
14
+ let mint_addr = setup.generate_address();
15
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
16
+
17
+ let config = SupplyControllerConfig {
18
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
19
+ allow_any_mint_burn: false,
20
+ whitelist_addresses: Vec::new(&setup.env),
21
+ };
22
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
23
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
24
+
25
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, true);
26
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
27
+
28
+ // Verify event
29
+ let expected =
30
+ MintWhitelistSet { supply_controller: controller.clone(), mint_address: mint_addr.clone(), active: true };
31
+ assert_eq_event(&setup.env, &setup.sac_manager, expected);
32
+
33
+ // Verify whitelist updated
34
+ assert!(sc_client.is_address_whitelisted(&controller, &mint_addr));
35
+ }
36
+
37
+ #[test]
38
+ fn test_set_mint_whitelist_add_fails_if_duplicate() {
39
+ let setup = TestSetup::new().build();
40
+ let controller = setup.generate_address();
41
+ let mint_addr = setup.generate_address();
42
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
43
+
44
+ let config = SupplyControllerConfig {
45
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
46
+ allow_any_mint_burn: false,
47
+ whitelist_addresses: Vec::new(&setup.env),
48
+ };
49
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
50
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
51
+
52
+ // Pre-populate the whitelist with mint_addr
53
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, true);
54
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
55
+
56
+ // Attempt to add the same address again — should fail
57
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, true);
58
+ let result = sc_client.try_set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
59
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::AlreadyExists.into());
60
+
61
+ // Verify whitelist remains unchanged after failed update.
62
+ assert!(sc_client.is_address_whitelisted(&controller, &mint_addr));
63
+ }
64
+
65
+ #[test]
66
+ fn test_set_mint_whitelist_add_by_non_manager_fails() {
67
+ let setup = TestSetup::new().build();
68
+ let non_manager = setup.generate_address();
69
+ let controller = setup.generate_address();
70
+ let mint_addr = setup.generate_address();
71
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
72
+
73
+ let config = SupplyControllerConfig {
74
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
75
+ allow_any_mint_burn: false,
76
+ whitelist_addresses: Vec::new(&setup.env),
77
+ };
78
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
79
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config));
80
+
81
+ mock_set_mint_whitelist_auth(&setup, &non_manager, &controller, &mint_addr, true);
82
+ let result = sc_client.try_set_mint_whitelist(&non_manager, &controller, &mint_addr, &true);
83
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::Unauthorized.into());
84
+ }
85
+
86
+ #[test]
87
+ #[should_panic(expected = "Error(Auth, InvalidAction)")]
88
+ fn test_set_mint_whitelist_add_without_auth() {
89
+ let setup = TestSetup::new().build();
90
+ let controller = setup.generate_address();
91
+ let mint_addr = setup.generate_address();
92
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
93
+
94
+ let config = SupplyControllerConfig {
95
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
96
+ allow_any_mint_burn: false,
97
+ whitelist_addresses: Vec::new(&setup.env),
98
+ };
99
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
100
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
101
+
102
+ // sc_manager's auth is not mocked — sender.require_auth() fails
103
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
104
+ }
105
+
106
+ #[test]
107
+ fn test_set_mint_whitelist_remove() {
108
+ let setup = TestSetup::new().build();
109
+ let controller = setup.generate_address();
110
+ let mint_addr = setup.generate_address();
111
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
112
+
113
+ let config = SupplyControllerConfig {
114
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
115
+ allow_any_mint_burn: false,
116
+ whitelist_addresses: Vec::new(&setup.env),
117
+ };
118
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
119
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
120
+
121
+ // Pre-populate the whitelist with mint_addr
122
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, true);
123
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
124
+
125
+ // Now remove it
126
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, false);
127
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &false);
128
+
129
+ // Verify event
130
+ let expected =
131
+ MintWhitelistSet { supply_controller: controller.clone(), mint_address: mint_addr.clone(), active: false };
132
+ assert_eq_event(&setup.env, &setup.sac_manager, expected);
133
+
134
+ // Verify whitelist updated
135
+ assert!(!sc_client.is_address_whitelisted(&controller, &mint_addr));
136
+ }
137
+
138
+ #[test]
139
+ fn test_set_mint_whitelist_remove_fails_if_not_in_whitelist() {
140
+ let setup = TestSetup::new().build();
141
+ let controller = setup.generate_address();
142
+ let not_whitelisted = setup.generate_address();
143
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
144
+
145
+ let config = SupplyControllerConfig {
146
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
147
+ allow_any_mint_burn: false,
148
+ whitelist_addresses: Vec::new(&setup.env),
149
+ };
150
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
151
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
152
+
153
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &not_whitelisted, false);
154
+ let result = sc_client.try_set_mint_whitelist(&setup.sc_manager, &controller, &not_whitelisted, &false);
155
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::NotFound.into());
156
+
157
+ // Verify whitelist remains unchanged after failed update.
158
+ assert!(!sc_client.is_address_whitelisted(&controller, &not_whitelisted));
159
+ }
160
+
161
+ #[test]
162
+ fn test_set_mint_whitelist_remove_by_non_manager_fails() {
163
+ let setup = TestSetup::new().build();
164
+ let non_manager = setup.generate_address();
165
+ let controller = setup.generate_address();
166
+ let mint_addr = setup.generate_address();
167
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
168
+
169
+ let config = SupplyControllerConfig {
170
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
171
+ allow_any_mint_burn: false,
172
+ whitelist_addresses: Vec::new(&setup.env),
173
+ };
174
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
175
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config));
176
+
177
+ // Pre-populate the whitelist with mint_addr
178
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, true);
179
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
180
+
181
+ // Non-manager tries to remove — should fail
182
+ mock_set_mint_whitelist_auth(&setup, &non_manager, &controller, &mint_addr, false);
183
+ let result = sc_client.try_set_mint_whitelist(&non_manager, &controller, &mint_addr, &false);
184
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::Unauthorized.into());
185
+ }
186
+
187
+ #[test]
188
+ fn test_set_mint_whitelist_fails_if_supply_controller_not_found() {
189
+ let setup = TestSetup::new().build();
190
+ let non_controller = setup.generate_address();
191
+ let mint_addr = setup.generate_address();
192
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
193
+
194
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &non_controller, &mint_addr, true);
195
+ let result = sc_client.try_set_mint_whitelist(&setup.sc_manager, &non_controller, &mint_addr, &true);
196
+ assert_eq!(result.err().unwrap().unwrap(), SupplyControlError::NotFound.into());
197
+ }
198
+
199
+ #[test]
200
+ fn test_set_mint_whitelist_preserves_limit_and_allow_any() {
201
+ let setup = TestSetup::new().build();
202
+ let controller = setup.generate_address();
203
+ let mint_addr = setup.generate_address();
204
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
205
+
206
+ let config = SupplyControllerConfig {
207
+ limit_config: LimitConfig { limit_capacity: 2_000, refill_per_second: 20 },
208
+ allow_any_mint_burn: true,
209
+ whitelist_addresses: Vec::new(&setup.env),
210
+ };
211
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
212
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
213
+
214
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, true);
215
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
216
+
217
+ let stored = sc_client.get_supply_controller_config(&controller).unwrap();
218
+ assert_eq!(stored.limit_config, config.limit_config);
219
+ assert_eq!(stored.allow_any_mint_burn, config.allow_any_mint_burn);
220
+ assert!(sc_client.is_address_whitelisted(&controller, &mint_addr));
221
+ }
222
+
223
+ #[test]
224
+ #[should_panic(expected = "Error(Auth, InvalidAction)")]
225
+ fn test_set_mint_whitelist_remove_without_auth() {
226
+ let setup = TestSetup::new().build();
227
+ let controller = setup.generate_address();
228
+ let mint_addr = setup.generate_address();
229
+ let sc_client = SupplyControlClient::new(&setup.env, &setup.sac_manager);
230
+
231
+ let config = SupplyControllerConfig {
232
+ limit_config: LimitConfig { limit_capacity: 1_000, refill_per_second: 0 },
233
+ allow_any_mint_burn: false,
234
+ whitelist_addresses: Vec::new(&setup.env),
235
+ };
236
+ mock_set_supply_controller_auth(&setup, &setup.sc_manager, &controller, &Some(config.clone()));
237
+ sc_client.set_supply_controller(&setup.sc_manager, &controller, &Some(config.clone()));
238
+
239
+ // Pre-populate the whitelist with mint_addr
240
+ mock_set_mint_whitelist_auth(&setup, &setup.sc_manager, &controller, &mint_addr, true);
241
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &true);
242
+
243
+ // sc_manager's auth is not mocked — sender.require_auth() fails
244
+ sc_client.set_mint_whitelist(&setup.sc_manager, &controller, &mint_addr, &false);
245
+ }