@layerzerolabs/protocol-stellar-v2 0.2.20 → 0.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/.turbo/turbo-build.log +783 -802
  2. package/.turbo/turbo-lint.log +320 -157
  3. package/.turbo/turbo-test.log +1414 -1457
  4. package/Cargo.lock +109 -108
  5. package/Cargo.toml +32 -18
  6. package/contracts/common-macros/Cargo.toml +7 -7
  7. package/contracts/common-macros/src/auth.rs +18 -37
  8. package/contracts/common-macros/src/contract_ttl.rs +2 -2
  9. package/contracts/common-macros/src/lib.rs +27 -10
  10. package/contracts/common-macros/src/lz_contract.rs +38 -7
  11. package/contracts/common-macros/src/storage.rs +251 -292
  12. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +6 -12
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +12 -17
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +2 -7
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +20 -9
  16. package/contracts/common-macros/src/tests/upgradeable.rs +26 -4
  17. package/contracts/common-macros/src/ttl_configurable.rs +2 -10
  18. package/contracts/common-macros/src/ttl_extendable.rs +2 -10
  19. package/contracts/common-macros/src/upgradeable.rs +56 -15
  20. package/contracts/common-macros/src/utils.rs +0 -9
  21. package/contracts/endpoint-v2/src/lib.rs +3 -2
  22. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +2 -2
  23. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +3 -3
  24. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +4 -4
  25. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +17 -5
  26. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  27. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +2 -2
  28. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +2 -2
  29. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +6 -6
  30. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +67 -37
  31. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +5 -5
  32. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +44 -54
  33. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +7 -7
  34. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +8 -8
  35. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +3 -3
  36. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +4 -4
  37. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +3 -3
  38. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +2 -2
  39. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +3 -3
  40. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +2 -2
  41. package/contracts/layerzero-views/Cargo.toml +0 -1
  42. package/contracts/layerzero-views/src/layerzero_view.rs +1 -13
  43. package/contracts/macro-integration-tests/Cargo.toml +5 -15
  44. package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +48 -0
  45. package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +170 -0
  46. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +154 -0
  47. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +338 -0
  48. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +435 -0
  49. package/contracts/macro-integration-tests/tests/runtime.rs +1 -0
  50. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.rs +8 -0
  51. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -0
  52. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +8 -0
  53. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +71 -0
  54. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.rs +10 -0
  55. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +5 -0
  56. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.rs +8 -0
  57. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -0
  58. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.rs +8 -0
  59. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -0
  60. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +38 -0
  61. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +96 -0
  62. package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +64 -0
  63. package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +46 -0
  64. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +8 -0
  65. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +1 -1
  66. package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +1 -1
  67. package/contracts/macro-integration-tests/tests/ui_oapp.rs +11 -0
  68. package/contracts/message-libs/message-lib-common/Cargo.toml +0 -1
  69. package/contracts/message-libs/message-lib-common/src/errors.rs +1 -1
  70. package/contracts/message-libs/treasury/Cargo.toml +0 -2
  71. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +2 -2
  72. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +2 -2
  73. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +2 -2
  74. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +2 -2
  75. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +2 -2
  76. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +2 -2
  77. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +7 -27
  78. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +2 -2
  79. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +2 -2
  80. package/contracts/oapps/counter/Cargo.toml +4 -6
  81. package/contracts/oapps/counter/integration_tests/utils.rs +19 -12
  82. package/contracts/oapps/oapp/src/errors.rs +1 -1
  83. package/contracts/oapps/oapp/src/interfaces/mod.rs +3 -0
  84. package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +47 -0
  85. package/contracts/oapps/oapp/src/lib.rs +1 -0
  86. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +4 -4
  87. package/contracts/oapps/oapp/src/oapp_core.rs +5 -5
  88. package/contracts/oapps/oapp/src/oapp_options_type3.rs +12 -4
  89. package/contracts/oapps/oapp/src/oapp_receiver.rs +14 -9
  90. package/contracts/oapps/oapp/src/tests/mod.rs +4 -4
  91. package/contracts/oapps/oapp/src/tests/{test_oapp_core.rs → oapp_core.rs} +4 -4
  92. package/contracts/oapps/oapp/src/tests/{test_oapp_options_type3.rs → oapp_options_type3.rs} +3 -4
  93. package/contracts/oapps/oapp-macros/Cargo.toml +8 -4
  94. package/contracts/oapps/oapp-macros/src/generators.rs +9 -34
  95. package/contracts/oapps/oapp-macros/src/lib.rs +3 -0
  96. package/contracts/oapps/oapp-macros/src/tests/mod.rs +2 -0
  97. package/contracts/oapps/oapp-macros/src/tests/oapp.rs +88 -0
  98. package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +86 -0
  99. package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +103 -0
  100. package/contracts/oapps/oft/integration-tests/utils.rs +28 -8
  101. package/contracts/oapps/oft/src/extensions/oft_fee.rs +136 -74
  102. package/contracts/oapps/oft/src/extensions/pausable.rs +44 -10
  103. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +170 -130
  104. package/contracts/oapps/oft/src/oft.rs +19 -12
  105. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -1
  106. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -1
  107. package/contracts/oapps/oft-core/Cargo.toml +1 -4
  108. package/contracts/oapps/oft-core/integration-tests/setup.rs +2 -2
  109. package/contracts/oapps/oft-core/integration-tests/utils.rs +21 -3
  110. package/contracts/oapps/oft-core/src/errors.rs +3 -2
  111. package/contracts/oapps/oft-core/src/events.rs +6 -0
  112. package/contracts/oapps/oft-core/src/lib.rs +1 -1
  113. package/contracts/oapps/oft-core/src/oft_core.rs +115 -60
  114. package/contracts/oapps/oft-core/src/storage.rs +7 -3
  115. package/contracts/oapps/oft-core/src/tests/mod.rs +1 -0
  116. package/contracts/oapps/oft-core/src/tests/test_decimals.rs +37 -2
  117. package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +2 -2
  118. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +323 -0
  119. package/contracts/oapps/oft-core/src/tests/test_send.rs +2 -2
  120. package/contracts/oapps/oft-core/src/tests/test_utils.rs +59 -14
  121. package/contracts/utils/Cargo.toml +0 -1
  122. package/contracts/utils/src/errors.rs +1 -1
  123. package/contracts/utils/src/multisig.rs +17 -8
  124. package/contracts/utils/src/ownable.rs +6 -6
  125. package/contracts/utils/src/testing_utils.rs +124 -54
  126. package/contracts/utils/src/tests/multisig.rs +12 -12
  127. package/contracts/utils/src/tests/ownable.rs +6 -6
  128. package/contracts/utils/src/tests/testing_utils.rs +50 -167
  129. package/contracts/utils/src/tests/ttl_configurable.rs +5 -5
  130. package/contracts/utils/src/tests/upgradeable.rs +1 -1
  131. package/contracts/utils/src/ttl_configurable.rs +10 -4
  132. package/contracts/utils/src/upgradeable.rs +5 -5
  133. package/contracts/workers/dvn/Cargo.toml +5 -6
  134. package/contracts/workers/dvn/src/dvn.rs +2 -12
  135. package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
  136. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +37 -19
  137. package/contracts/workers/dvn-fee-lib/src/lib.rs +12 -2
  138. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +15 -13
  139. package/contracts/workers/executor/Cargo.toml +3 -0
  140. package/contracts/workers/executor/src/executor.rs +2 -12
  141. package/contracts/workers/executor/src/lib.rs +2 -2
  142. package/contracts/workers/executor/src/tests/auth.rs +394 -0
  143. package/contracts/workers/executor/src/tests/executor.rs +410 -0
  144. package/contracts/workers/executor/src/tests/mod.rs +3 -0
  145. package/contracts/workers/executor/src/tests/setup.rs +250 -0
  146. package/contracts/workers/executor-fee-lib/Cargo.toml +5 -0
  147. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +1 -12
  148. package/contracts/workers/executor-fee-lib/src/lib.rs +8 -2
  149. package/contracts/workers/executor-helper/Cargo.toml +0 -1
  150. package/contracts/workers/price-feed/Cargo.toml +5 -0
  151. package/contracts/workers/price-feed/src/lib.rs +9 -4
  152. package/contracts/workers/price-feed/src/price_feed.rs +1 -11
  153. package/contracts/workers/worker/src/errors.rs +1 -1
  154. package/contracts/workers/worker/src/tests/setup.rs +1 -1
  155. package/contracts/workers/worker/src/tests/worker.rs +55 -41
  156. package/contracts/workers/worker/src/worker.rs +34 -25
  157. package/docs/error-spec.md +55 -0
  158. package/docs/layerzero-v2-on-stellar.md +447 -0
  159. package/docs/oapp-guide.md +212 -0
  160. package/docs/oft-guide.md +314 -0
  161. package/package.json +3 -3
  162. package/sdk/.turbo/turbo-test.log +260 -257
  163. package/sdk/dist/generated/bml.d.ts +3 -3
  164. package/sdk/dist/generated/bml.js +4 -4
  165. package/sdk/dist/generated/counter.d.ts +295 -295
  166. package/sdk/dist/generated/counter.js +43 -43
  167. package/sdk/dist/generated/dvn.d.ts +91 -91
  168. package/sdk/dist/generated/dvn.js +24 -24
  169. package/sdk/dist/generated/dvn_fee_lib.d.ts +92 -92
  170. package/sdk/dist/generated/dvn_fee_lib.js +25 -25
  171. package/sdk/dist/generated/endpoint.d.ts +99 -99
  172. package/sdk/dist/generated/endpoint.js +16 -16
  173. package/sdk/dist/generated/executor.d.ts +91 -91
  174. package/sdk/dist/generated/executor.js +24 -24
  175. package/sdk/dist/generated/executor_fee_lib.d.ts +92 -92
  176. package/sdk/dist/generated/executor_fee_lib.js +25 -25
  177. package/sdk/dist/generated/executor_helper.d.ts +3 -3
  178. package/sdk/dist/generated/executor_helper.js +4 -4
  179. package/sdk/dist/generated/layerzero_view.d.ts +186 -186
  180. package/sdk/dist/generated/layerzero_view.js +35 -35
  181. package/sdk/dist/generated/oft.d.ts +366 -352
  182. package/sdk/dist/generated/oft.js +74 -79
  183. package/sdk/dist/generated/price_feed.d.ts +198 -198
  184. package/sdk/dist/generated/price_feed.js +39 -39
  185. package/sdk/dist/generated/sml.d.ts +99 -99
  186. package/sdk/dist/generated/sml.js +16 -16
  187. package/sdk/dist/generated/treasury.d.ts +99 -99
  188. package/sdk/dist/generated/treasury.js +16 -16
  189. package/sdk/dist/generated/uln302.d.ts +99 -99
  190. package/sdk/dist/generated/uln302.js +16 -16
  191. package/sdk/dist/generated/upgrader.d.ts +3 -3
  192. package/sdk/dist/generated/upgrader.js +3 -3
  193. package/sdk/package.json +1 -1
  194. package/sdk/test/suites/localnet.ts +84 -20
  195. package/contracts/ERROR_SPEC.md +0 -51
  196. package/contracts/endpoint-v2/ARCHITECTURE.md +0 -233
  197. /package/contracts/oapps/oapp/src/tests/{test_oapp_receiver.rs → oapp_receiver.rs} +0 -0
  198. /package/contracts/oapps/oapp/src/tests/{test_oapp_sender.rs → oapp_sender.rs} +0 -0
@@ -1,6 +1,6 @@
1
1
  //! Utility functions for OFT-STD integration tests.
2
2
 
3
- use crate::extensions::rate_limiter::Direction;
3
+ use crate::extensions::rate_limiter::{Direction, 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;
@@ -254,10 +254,28 @@ pub fn try_lz_receive(
254
254
 
255
255
  // returns (encoded_payload, options, send_library)
256
256
  pub fn scan_packet_sent_event(env: &Env, endpoint: &Address) -> Option<(Bytes, Bytes, Address)> {
257
+ use soroban_sdk::TryFromVal;
258
+
257
259
  let mut packet = None;
258
- for (emitter, topics, data) in env.events().all() {
259
- let packet_sent_symbol = Symbol::new(env, "packet_sent").to_val();
260
- if emitter == *endpoint && topics.contains(packet_sent_symbol) {
260
+ let events = env.events().all().filter_by_contract(endpoint);
261
+ for event in events.events().iter() {
262
+ let v0 = match &event.body {
263
+ soroban_sdk::xdr::ContractEventBody::V0(v0) => v0,
264
+ };
265
+
266
+ // Check if this is a packet_sent event by looking at topics
267
+ let mut is_packet_sent = false;
268
+ for topic in v0.topics.iter() {
269
+ if let Ok(sym) = Symbol::try_from_val(env, topic) {
270
+ if sym == Symbol::new(env, "packet_sent") {
271
+ is_packet_sent = true;
272
+ break;
273
+ }
274
+ }
275
+ }
276
+
277
+ if is_packet_sent {
278
+ let data: Val = Val::try_from_val(env, &v0.data).unwrap();
261
279
  let map: Map<Symbol, Val> = data.into_val(env);
262
280
 
263
281
  let encoded_payload: Bytes = map.get(Symbol::new(env, "encoded_packet")).unwrap().into_val(env);
@@ -359,16 +377,17 @@ pub fn set_default_fee_bps(env: &Env, chain: &ChainSetup<'_>, fee_bps: u64) {
359
377
  }
360
378
 
361
379
  pub fn set_fee_bps(env: &Env, chain: &ChainSetup<'_>, dst_eid: u32, fee_bps: u64) {
380
+ let fee_bps_opt = Some(fee_bps);
362
381
  env.mock_auths(&[MockAuth {
363
382
  address: &chain.owner,
364
383
  invoke: &MockAuthInvoke {
365
384
  contract: &chain.oft.address,
366
385
  fn_name: "set_fee_bps",
367
- args: (&dst_eid, &fee_bps).into_val(env),
386
+ args: (&dst_eid, &fee_bps_opt).into_val(env),
368
387
  sub_invokes: &[],
369
388
  },
370
389
  }]);
371
- chain.oft.set_fee_bps(&dst_eid, &fee_bps);
390
+ chain.oft.set_fee_bps(&dst_eid, &fee_bps_opt);
372
391
  }
373
392
 
374
393
  // ============================================================================
@@ -383,16 +402,17 @@ pub fn set_rate_limit(
383
402
  limit: i128,
384
403
  window_seconds: u64,
385
404
  ) {
405
+ let config = Some(RateLimitConfig { limit, window_seconds });
386
406
  env.mock_auths(&[MockAuth {
387
407
  address: &chain.owner,
388
408
  invoke: &MockAuthInvoke {
389
409
  contract: &chain.oft.address,
390
410
  fn_name: "set_rate_limit",
391
- args: (direction, &dst_eid, &limit, &window_seconds).into_val(env),
411
+ args: (direction, &dst_eid, &config).into_val(env),
392
412
  sub_invokes: &[],
393
413
  },
394
414
  }]);
395
- chain.oft.set_rate_limit(direction, &dst_eid, &limit, &window_seconds);
415
+ chain.oft.set_rate_limit(direction, &dst_eid, &config);
396
416
  }
397
417
 
398
418
  pub fn rate_limit_capacity(chain: &ChainSetup<'_>, direction: &Direction, eid: u32) -> i128 {
@@ -1,6 +1,6 @@
1
1
  use common_macros::{contract_error, contract_trait, only_auth, storage};
2
2
  use soroban_sdk::{assert_with_error, contractevent, token::TokenClient, Address, Env};
3
- use utils::{option_ext::OptionExt, ownable::Ownable};
3
+ use utils::{auth::Auth, option_ext::OptionExt};
4
4
 
5
5
  /// Base fee in basis points (10,000 BPS = 100%)
6
6
  /// Used as denominator in fee calculations
@@ -12,13 +12,18 @@ const BASE_FEE_BPS: u64 = 10_000;
12
12
 
13
13
  #[storage]
14
14
  pub enum OFTFeeStorage {
15
+ /// Default fee rate in basis points (0-10,000, where 10,000 = 100%)
16
+ /// Applied to destinations without specific fee configuration
17
+ /// No fee is charged(default to 0) by default
15
18
  #[instance(u64)]
16
19
  #[default(0)]
17
20
  DefaultFeeBps,
18
21
 
22
+ /// Destination-specific fee rates mapped by endpoint ID (eid)
19
23
  #[persistent(u64)]
20
24
  FeeBps { eid: u32 },
21
25
 
26
+ /// Address where collected fees will be deposited
22
27
  #[instance(Address)]
23
28
  FeeDepositAddress,
24
29
  }
@@ -31,7 +36,6 @@ pub enum OFTFeeStorage {
31
36
  pub enum OFTFeeError {
32
37
  InvalidFeeBps = 3100,
33
38
  InvalidFeeDepositAddress,
34
- NotFound,
35
39
  SameValue,
36
40
  }
37
41
 
@@ -49,13 +53,8 @@ pub struct DefaultFeeBpsSet {
49
53
  #[derive(Clone, Debug, Eq, PartialEq)]
50
54
  pub struct FeeBpsSet {
51
55
  pub dst_eid: u32,
52
- pub fee_bps: u64,
53
- }
54
-
55
- #[contractevent]
56
- #[derive(Clone, Debug, Eq, PartialEq)]
57
- pub struct FeeBpsUnset {
58
- pub dst_eid: u32,
56
+ /// The fee rate in basis points, or None if the fee is removed
57
+ pub fee_bps: Option<u64>,
59
58
  }
60
59
 
61
60
  #[contractevent]
@@ -69,71 +68,65 @@ pub struct FeeDepositAddressSet {
69
68
  // =========================================================================
70
69
 
71
70
  #[contract_trait]
72
- pub trait OFTFee: OFTFeeInternal + Ownable {
73
- #[only_auth]
74
- fn set_default_fee_bps(env: &Env, default_fee_bps: u64) {
75
- assert_with_error!(env, default_fee_bps <= BASE_FEE_BPS, OFTFeeError::InvalidFeeBps);
76
- let current_default = OFTFeeStorage::default_fee_bps(env);
77
- assert_with_error!(env, current_default != default_fee_bps, OFTFeeError::SameValue);
78
- OFTFeeStorage::set_default_fee_bps(env, &default_fee_bps);
79
- DefaultFeeBpsSet { fee_bps: default_fee_bps }.publish(env);
80
- }
71
+ pub trait OFTFee: OFTFeeInternal + Auth {
72
+ // =========================================================================
73
+ // Management Functions
74
+ // =========================================================================
81
75
 
76
+ /// Sets the default fee rate in basis points.
82
77
  #[only_auth]
83
- fn set_fee_bps(env: &Env, dst_eid: u32, fee_bps: u64) {
84
- assert_with_error!(env, fee_bps <= BASE_FEE_BPS, OFTFeeError::InvalidFeeBps);
85
- if OFTFeeStorage::has_fee_bps(env, dst_eid) {
86
- let current_fee_bps = OFTFeeStorage::fee_bps(env, dst_eid).unwrap();
87
- assert_with_error!(env, current_fee_bps != fee_bps, OFTFeeError::SameValue);
88
- }
89
- OFTFeeStorage::set_fee_bps(env, dst_eid, &fee_bps);
90
- FeeBpsSet { dst_eid, fee_bps }.publish(env);
78
+ fn set_default_fee_bps(env: &soroban_sdk::Env, default_fee_bps: u64) {
79
+ Self::__set_default_fee_bps(env, default_fee_bps);
91
80
  }
92
81
 
82
+ /// Sets or removes the fee rate for a specific destination endpoint.
83
+ ///
84
+ /// # Arguments
85
+ /// * `dst_eid` - The destination endpoint ID
86
+ /// * `fee_bps` - The fee rate (0-10,000), or None to remove the fee configuration
93
87
  #[only_auth]
94
- fn unset_fee_bps(env: &Env, dst_eid: u32) {
95
- assert_with_error!(env, OFTFeeStorage::has_fee_bps(env, dst_eid), OFTFeeError::NotFound);
96
- OFTFeeStorage::remove_fee_bps(env, dst_eid);
97
- FeeBpsUnset { dst_eid }.publish(env);
88
+ fn set_fee_bps(env: &soroban_sdk::Env, dst_eid: u32, fee_bps: Option<u64>) {
89
+ Self::__set_fee_bps(env, dst_eid, fee_bps);
98
90
  }
99
91
 
92
+ /// Sets the address where collected fees will be deposited.
100
93
  #[only_auth]
101
- fn set_fee_deposit_address(env: &Env, fee_deposit_address: Address) {
102
- if let Some(current_address) = OFTFeeStorage::fee_deposit_address(env) {
103
- assert_with_error!(env, current_address != fee_deposit_address, OFTFeeError::SameValue);
104
- }
105
- OFTFeeStorage::set_fee_deposit_address(env, &fee_deposit_address);
106
- FeeDepositAddressSet { fee_deposit_address }.publish(env);
94
+ fn set_fee_deposit_address(env: &soroban_sdk::Env, fee_deposit_address: soroban_sdk::Address) {
95
+ Self::__set_fee_deposit_address(env, &fee_deposit_address);
107
96
  }
108
97
 
109
- fn has_fee_bps(env: &Env, dst_eid: u32) -> bool {
110
- Self::effective_fee_bps(env, dst_eid) > 0
111
- }
98
+ // =========================================================================
99
+ // View Functions
100
+ // =========================================================================
112
101
 
113
- fn effective_fee_bps(env: &Env, dst_eid: u32) -> u64 {
114
- if OFTFeeStorage::has_fee_bps(env, dst_eid) {
115
- OFTFeeStorage::fee_bps(env, dst_eid).unwrap()
116
- } else {
117
- OFTFeeStorage::default_fee_bps(env)
118
- }
102
+ /// Returns the default fee rate in basis points.
103
+ fn default_fee_bps(env: &soroban_sdk::Env) -> u64 {
104
+ Self::__default_fee_bps(env)
119
105
  }
120
106
 
121
- fn default_fee_bps(env: &Env) -> u64 {
122
- OFTFeeStorage::default_fee_bps(env)
107
+ /// Returns the fee rate for a specific destination, if set.
108
+ fn fee_bps(env: &soroban_sdk::Env, dst_eid: u32) -> Option<u64> {
109
+ Self::__fee_bps(env, dst_eid)
123
110
  }
124
111
 
125
- fn fee_bps(env: &Env, dst_eid: u32) -> Option<u64> {
126
- OFTFeeStorage::fee_bps(env, dst_eid)
112
+ /// Returns the effective fee rate for a destination (destination-specific or default).
113
+ fn effective_fee_bps(env: &soroban_sdk::Env, dst_eid: u32) -> u64 {
114
+ Self::__effective_fee_bps(env, dst_eid)
127
115
  }
128
116
 
129
- fn fee_deposit_address(env: &Env) -> Address {
130
- OFTFeeStorage::fee_deposit_address(env).unwrap_or_panic(env, OFTFeeError::InvalidFeeDepositAddress)
117
+ /// Returns the fee deposit address.
118
+ fn fee_deposit_address(env: &soroban_sdk::Env) -> soroban_sdk::Address {
119
+ Self::__fee_deposit_address(env)
131
120
  }
132
121
  }
133
122
 
134
123
  /// Internal trait for OFT fee operations used by OFT hooks.
135
- /// Contains only truly internal methods that are called from OFTInner implementations.
124
+ /// Contains only truly internal methods that are called from OFTInternal implementations.
136
125
  pub trait OFTFeeInternal {
126
+ // =========================================================================
127
+ // OFT Hooks
128
+ // =========================================================================
129
+
137
130
  /// Calculates the fee amount for a given transfer (read-only).
138
131
  /// Used internally by `__debit_view` to calculate the fee.
139
132
  ///
@@ -144,40 +137,109 @@ pub trait OFTFeeInternal {
144
137
  /// # Returns
145
138
  /// The fee amount to be deducted
146
139
  fn __fee_view(env: &Env, dst_eid: u32, amount_ld: i128) -> i128 {
147
- // Calculate effective fee (destination-specific or default)
148
- let fee_bps = if OFTFeeStorage::has_fee_bps(env, dst_eid) {
149
- OFTFeeStorage::fee_bps(env, dst_eid).unwrap()
150
- } else {
151
- OFTFeeStorage::default_fee_bps(env)
152
- };
140
+ let fee_bps = Self::__effective_fee_bps(env, dst_eid);
153
141
  if fee_bps == 0 {
154
142
  return 0;
155
143
  }
144
+
156
145
  // Check that fee deposit address is set (required for fee collection)
157
- assert_with_error!(
158
- env,
159
- OFTFeeStorage::fee_deposit_address(env).is_some(),
160
- OFTFeeError::InvalidFeeDepositAddress
161
- );
146
+ assert_with_error!(env, OFTFeeStorage::has_fee_deposit_address(env), OFTFeeError::InvalidFeeDepositAddress);
147
+
162
148
  (amount_ld * fee_bps as i128) / BASE_FEE_BPS as i128
163
149
  }
164
150
 
165
- /// Charges the fee by transferring the fee amount from sender to the fee deposit address.
166
- /// Used internally by `__debit` to collect the fee (mirrors `__debit`).
151
+ /// Charges the fee by transferring the fee amount from the sender to the fee deposit address.
152
+ /// Used internally by `__debit` to collect the fee.
167
153
  ///
168
154
  /// # Arguments
169
155
  /// * `token` - The token address to transfer
170
- /// * `sender` - The sender address to transfer fee from
156
+ /// * `from` - The address to transfer fee from
171
157
  /// * `fee_amount` - The fee amount to transfer
172
- fn __charge_fee(env: &Env, token: &Address, sender: &Address, fee_amount: i128) {
158
+ fn __charge_fee(env: &Env, token: &Address, from: &Address, fee_amount: i128) {
173
159
  if fee_amount != 0 {
174
- assert_with_error!(
175
- env,
176
- OFTFeeStorage::fee_deposit_address(env).is_some(),
177
- OFTFeeError::InvalidFeeDepositAddress
178
- );
179
- let fee_deposit = OFTFeeStorage::fee_deposit_address(env).unwrap();
180
- TokenClient::new(env, token).transfer(sender, &fee_deposit, &fee_amount);
160
+ let fee_deposit = Self::__fee_deposit_address(env);
161
+ TokenClient::new(env, token).transfer(from, &fee_deposit, &fee_amount);
162
+ }
163
+ }
164
+
165
+ // =========================================================================
166
+ // Management Functions
167
+ // =========================================================================
168
+
169
+ /// Sets the default fee rate in basis points.
170
+ ///
171
+ /// # Arguments
172
+ /// * `default_fee_bps` - The default fee rate (0-10,000, where 10,000 = 100%)
173
+ fn __set_default_fee_bps(env: &Env, default_fee_bps: u64) {
174
+ assert_with_error!(env, default_fee_bps <= BASE_FEE_BPS, OFTFeeError::InvalidFeeBps);
175
+
176
+ let current_default = Self::__default_fee_bps(env);
177
+ assert_with_error!(env, current_default != default_fee_bps, OFTFeeError::SameValue);
178
+
179
+ OFTFeeStorage::set_default_fee_bps(env, &default_fee_bps);
180
+
181
+ DefaultFeeBpsSet { fee_bps: default_fee_bps }.publish(env);
182
+ }
183
+
184
+ /// Sets or removes the fee rate for a specific destination endpoint.
185
+ ///
186
+ /// # Arguments
187
+ /// * `dst_eid` - The destination endpoint ID
188
+ /// * `fee_bps` - The fee rate (0-10,000), or None to remove the fee configuration
189
+ fn __set_fee_bps(env: &Env, dst_eid: u32, fee_bps: Option<u64>) {
190
+ let current_fee_bps = Self::__fee_bps(env, dst_eid);
191
+ assert_with_error!(env, current_fee_bps != fee_bps, OFTFeeError::SameValue);
192
+
193
+ match fee_bps {
194
+ Some(bps) => {
195
+ assert_with_error!(env, bps <= BASE_FEE_BPS, OFTFeeError::InvalidFeeBps);
196
+ OFTFeeStorage::set_fee_bps(env, dst_eid, &bps);
197
+ }
198
+ None => {
199
+ OFTFeeStorage::remove_fee_bps(env, dst_eid);
200
+ }
201
+ }
202
+
203
+ FeeBpsSet { dst_eid, fee_bps }.publish(env);
204
+ }
205
+
206
+ /// Sets the address where collected fees will be deposited.
207
+ ///
208
+ /// # Arguments
209
+ /// * `fee_deposit_address` - The address to deposit fees to
210
+ fn __set_fee_deposit_address(env: &Env, fee_deposit_address: &Address) {
211
+ if let Some(current_address) = OFTFeeStorage::fee_deposit_address(env) {
212
+ assert_with_error!(env, current_address != *fee_deposit_address, OFTFeeError::SameValue);
213
+ }
214
+ OFTFeeStorage::set_fee_deposit_address(env, fee_deposit_address);
215
+ FeeDepositAddressSet { fee_deposit_address: fee_deposit_address.clone() }.publish(env);
216
+ }
217
+
218
+ // =========================================================================
219
+ // View Functions
220
+ // =========================================================================
221
+
222
+ /// Returns the effective fee rate for a destination (destination-specific or default).
223
+ fn __effective_fee_bps(env: &Env, dst_eid: u32) -> u64 {
224
+ if OFTFeeStorage::has_fee_bps(env, dst_eid) {
225
+ OFTFeeStorage::fee_bps(env, dst_eid).unwrap()
226
+ } else {
227
+ OFTFeeStorage::default_fee_bps(env)
181
228
  }
182
229
  }
230
+
231
+ /// Returns the default fee rate in basis points.
232
+ fn __default_fee_bps(env: &Env) -> u64 {
233
+ OFTFeeStorage::default_fee_bps(env)
234
+ }
235
+
236
+ /// Returns the fee rate for a specific destination, if set.
237
+ fn __fee_bps(env: &Env, dst_eid: u32) -> Option<u64> {
238
+ OFTFeeStorage::fee_bps(env, dst_eid)
239
+ }
240
+
241
+ /// Returns the fee deposit address.
242
+ fn __fee_deposit_address(env: &Env) -> Address {
243
+ OFTFeeStorage::fee_deposit_address(env).unwrap_or_panic(env, OFTFeeError::InvalidFeeDepositAddress)
244
+ }
183
245
  }
@@ -1,6 +1,6 @@
1
1
  use common_macros::{contract_error, contract_trait, only_auth, storage};
2
2
  use soroban_sdk::{assert_with_error, contractevent, Env};
3
- use utils::ownable::Ownable;
3
+ use utils::auth::Auth;
4
4
 
5
5
  // =========================================================================
6
6
  // Storage
@@ -38,28 +38,62 @@ pub struct PausedSet {
38
38
  // =========================================================================
39
39
 
40
40
  #[contract_trait]
41
- pub trait OFTPausable: OFTPausableInternal + Ownable {
41
+ pub trait OFTPausable: OFTPausableInternal + Auth {
42
+ /// Sets the paused state of the OFT.
43
+ ///
44
+ /// When paused, the OFT will reject new send/receive/quote_send/quote_oft operations.
45
+ ///
46
+ /// # Arguments
47
+ /// * `paused` - `true` to pause, `false` to unpause
42
48
  #[only_auth]
43
- fn set_paused(env: &Env, paused: bool) {
44
- assert_with_error!(env, Self::is_paused(env) != paused, OFTPausableError::PauseStatusUnchanged);
45
- OFTPausableStorage::set_paused(env, &paused);
46
- PausedSet { paused }.publish(env);
49
+ fn set_paused(env: &soroban_sdk::Env, paused: bool) {
50
+ Self::__set_paused(env, paused);
47
51
  }
48
52
 
49
- fn is_paused(env: &Env) -> bool {
50
- OFTPausableStorage::paused(env)
53
+ /// Returns the paused state of the OFT.
54
+ fn is_paused(env: &soroban_sdk::Env) -> bool {
55
+ Self::__is_paused(env)
51
56
  }
52
57
  }
53
58
 
54
59
  /// Internal trait for pausable operations used by OFT hooks.
55
60
  /// Contains only truly internal methods that are called from OFTInternal implementations.
56
61
  pub trait OFTPausableInternal {
62
+ // =========================================================================
63
+ // OFT Hooks
64
+ // =========================================================================
65
+
57
66
  /// Asserts that the OFT is not paused, panics otherwise.
58
- /// Used internally by `send`, `quote_send`, and `__lz_receive` to enforce pause state.
67
+ /// Used internally by `send`, `quote_send`, `quote_oft`, and `__lz_receive` to enforce pause state.
59
68
  ///
60
69
  /// # Errors
61
70
  /// * `Paused` - If the OFT is currently paused.
62
71
  fn __assert_not_paused(env: &Env) {
63
- assert_with_error!(env, !OFTPausableStorage::paused(env), OFTPausableError::Paused);
72
+ assert_with_error!(env, !Self::__is_paused(env), OFTPausableError::Paused);
73
+ }
74
+
75
+ // =========================================================================
76
+ // Management Functions
77
+ // =========================================================================
78
+
79
+ /// Sets the paused state of the OFT.
80
+ ///
81
+ /// When paused, the OFT will reject new send/receive/quote_send/quote_oft operations.
82
+ ///
83
+ /// # Arguments
84
+ /// * `paused` - `true` to pause, `false` to unpause
85
+ fn __set_paused(env: &Env, paused: bool) {
86
+ assert_with_error!(env, Self::__is_paused(env) != paused, OFTPausableError::PauseStatusUnchanged);
87
+ OFTPausableStorage::set_paused(env, &paused);
88
+ PausedSet { paused }.publish(env);
89
+ }
90
+
91
+ // =========================================================================
92
+ // View Functions
93
+ // =========================================================================
94
+
95
+ /// Returns the paused state of the OFT.
96
+ fn __is_paused(env: &Env) -> bool {
97
+ OFTPausableStorage::paused(env)
64
98
  }
65
99
  }