@layerzerolabs/protocol-stellar-v2 0.2.33 → 0.2.35

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 (123) hide show
  1. package/.turbo/turbo-build.log +351 -367
  2. package/.turbo/turbo-lint.log +220 -223
  3. package/.turbo/turbo-test.log +1993 -1796
  4. package/Cargo.lock +10 -10
  5. package/Cargo.toml +1 -1
  6. package/contracts/common-macros/src/storage.rs +7 -5
  7. package/contracts/common-macros/src/tests/storage/snapshots/common_macros__tests__storage__generate_storage__snapshot_generated_storage_code.snap +3 -3
  8. package/contracts/endpoint-v2/src/endpoint_v2.rs +5 -4
  9. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +7 -8
  10. package/contracts/endpoint-v2/src/messaging_channel.rs +78 -45
  11. package/contracts/endpoint-v2/src/storage.rs +8 -3
  12. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +2 -2
  13. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +12 -15
  14. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +46 -9
  15. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +7 -23
  16. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +23 -20
  17. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +94 -1
  18. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +17 -15
  19. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +1 -1
  20. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +48 -13
  21. package/contracts/endpoint-v2/src/tests/messaging_channel/pending_inbound_nonces.rs +111 -0
  22. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +15 -25
  23. package/contracts/layerzero-views/src/layerzero_view.rs +2 -2
  24. package/contracts/layerzero-views/src/tests/layerzero_view_tests.rs +3 -4
  25. package/contracts/layerzero-views/src/tests/setup.rs +0 -21
  26. package/contracts/message-libs/blocked-message-lib/src/lib.rs +4 -4
  27. package/contracts/message-libs/uln-302/src/send_uln.rs +5 -5
  28. package/contracts/oapps/counter/src/counter.rs +6 -0
  29. package/contracts/oapps/oapp/src/oapp_sender.rs +3 -2
  30. package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +5 -11
  31. package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +7 -14
  32. package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +11 -22
  33. package/contracts/oapps/oft/integration-tests/setup.rs +59 -7
  34. package/contracts/oapps/oft/integration-tests/utils.rs +28 -2
  35. package/contracts/oapps/oft/src/extensions/oft_fee.rs +5 -0
  36. package/contracts/oapps/oft/src/interfaces/mintable.rs +14 -0
  37. package/contracts/oapps/oft/src/interfaces/mod.rs +2 -2
  38. package/contracts/oapps/oft/src/oft.rs +8 -7
  39. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +8 -8
  40. package/contracts/oapps/oft/src/oft_types/mod.rs +3 -4
  41. package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +7 -5
  42. package/contracts/oapps/sac-manager/src/errors.rs +14 -0
  43. package/contracts/{sac-manager → oapps/sac-manager}/src/lib.rs +0 -4
  44. package/contracts/oapps/sac-manager/src/sac_manager.rs +115 -0
  45. package/contracts/oapps/sac-manager/src/storage.rs +20 -0
  46. package/contracts/{sac-manager → oapps/sac-manager}/src/tests/mod.rs +0 -4
  47. package/contracts/oapps/sac-manager/src/tests/sac_manager/clawback.rs +86 -0
  48. package/contracts/oapps/sac-manager/src/tests/sac_manager/mint.rs +58 -0
  49. package/contracts/{sac-manager → oapps/sac-manager}/src/tests/sac_manager/mod.rs +1 -3
  50. package/contracts/oapps/sac-manager/src/tests/sac_manager/set_minter.rs +69 -0
  51. package/contracts/oapps/sac-manager/src/tests/sac_manager/test_helper.rs +18 -0
  52. package/contracts/oapps/sac-manager/src/tests/sac_manager/view_functions.rs +28 -0
  53. package/contracts/{sac-manager → oapps/sac-manager}/src/tests/test_helper.rs +16 -59
  54. package/docs/layerzero-v2-on-stellar.md +46 -2
  55. package/package.json +8 -3
  56. package/sdk/.turbo/turbo-test.log +424 -429
  57. package/sdk/dist/generated/bml.d.ts +3 -3
  58. package/sdk/dist/generated/bml.js +3 -3
  59. package/sdk/dist/generated/counter.d.ts +32 -3
  60. package/sdk/dist/generated/counter.js +6 -3
  61. package/sdk/dist/generated/dvn.d.ts +3 -3
  62. package/sdk/dist/generated/dvn.js +3 -3
  63. package/sdk/dist/generated/dvn_fee_lib.d.ts +2 -2
  64. package/sdk/dist/generated/dvn_fee_lib.js +2 -2
  65. package/sdk/dist/generated/endpoint.d.ts +12 -13
  66. package/sdk/dist/generated/endpoint.js +7 -7
  67. package/sdk/dist/generated/executor.d.ts +3 -3
  68. package/sdk/dist/generated/executor.js +3 -3
  69. package/sdk/dist/generated/executor_fee_lib.d.ts +2 -2
  70. package/sdk/dist/generated/executor_fee_lib.js +2 -2
  71. package/sdk/dist/generated/executor_helper.d.ts +2 -2
  72. package/sdk/dist/generated/executor_helper.js +2 -2
  73. package/sdk/dist/generated/layerzero_view.d.ts +3 -3
  74. package/sdk/dist/generated/layerzero_view.js +3 -3
  75. package/sdk/dist/generated/oft.d.ts +32 -3
  76. package/sdk/dist/generated/oft.js +7 -4
  77. package/sdk/dist/generated/price_feed.d.ts +3 -3
  78. package/sdk/dist/generated/price_feed.js +3 -3
  79. package/sdk/dist/generated/sac_manager.d.ts +47 -318
  80. package/sdk/dist/generated/sac_manager.js +24 -129
  81. package/sdk/dist/generated/sml.d.ts +2 -2
  82. package/sdk/dist/generated/sml.js +2 -2
  83. package/sdk/dist/generated/treasury.d.ts +2 -2
  84. package/sdk/dist/generated/treasury.js +2 -2
  85. package/sdk/dist/generated/uln302.d.ts +3 -3
  86. package/sdk/dist/generated/uln302.js +3 -3
  87. package/sdk/dist/generated/upgrader.d.ts +2 -2
  88. package/sdk/dist/generated/upgrader.js +2 -2
  89. package/sdk/package.json +6 -1
  90. package/sdk/test/oft-sml.test.ts +72 -36
  91. package/sdk/test/sac-manager-redistribution.test.ts +38 -182
  92. package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +0 -39
  93. package/contracts/oapps/oft/src/interfaces/mint_burnable.rs +0 -18
  94. package/contracts/sac-manager/src/errors.rs +0 -18
  95. package/contracts/sac-manager/src/extensions/mod.rs +0 -6
  96. package/contracts/sac-manager/src/extensions/redistribution.rs +0 -109
  97. package/contracts/sac-manager/src/extensions/supply_control/mod.rs +0 -488
  98. package/contracts/sac-manager/src/extensions/supply_control/rate_limit.rs +0 -126
  99. package/contracts/sac-manager/src/interfaces/mod.rs +0 -3
  100. package/contracts/sac-manager/src/interfaces/sac_manager.rs +0 -52
  101. package/contracts/sac-manager/src/sac_manager.rs +0 -193
  102. package/contracts/sac-manager/src/storage.rs +0 -20
  103. package/contracts/sac-manager/src/tests/redistribution/mod.rs +0 -1
  104. package/contracts/sac-manager/src/tests/redistribution/redistribute_funds.rs +0 -82
  105. package/contracts/sac-manager/src/tests/sac_manager/admin_mint.rs +0 -206
  106. package/contracts/sac-manager/src/tests/sac_manager/burn.rs +0 -215
  107. package/contracts/sac-manager/src/tests/sac_manager/clawback.rs +0 -209
  108. package/contracts/sac-manager/src/tests/sac_manager/mint.rs +0 -252
  109. package/contracts/sac-manager/src/tests/sac_manager/set_oft_address.rs +0 -47
  110. package/contracts/sac-manager/src/tests/sac_manager/test_helper.rs +0 -75
  111. package/contracts/sac-manager/src/tests/sac_manager/view_functions.rs +0 -60
  112. package/contracts/sac-manager/src/tests/supply_control/enumerable_set.rs +0 -256
  113. package/contracts/sac-manager/src/tests/supply_control/mod.rs +0 -8
  114. package/contracts/sac-manager/src/tests/supply_control/refill.rs +0 -90
  115. package/contracts/sac-manager/src/tests/supply_control/set_mint_whitelist.rs +0 -245
  116. package/contracts/sac-manager/src/tests/supply_control/set_supply_controller.rs +0 -267
  117. package/contracts/sac-manager/src/tests/supply_control/set_supply_controller_manager.rs +0 -122
  118. package/contracts/sac-manager/src/tests/supply_control/test_helper.rs +0 -38
  119. package/contracts/sac-manager/src/tests/supply_control/update_allow_any_mint_burn.rs +0 -114
  120. package/contracts/sac-manager/src/tests/supply_control/update_limit_config.rs +0 -257
  121. /package/contracts/{sac-manager → oapps/sac-manager}/Cargo.toml +0 -0
  122. /package/contracts/{sac-manager → oapps/sac-manager}/src/tests/sac_manager/set_admin.rs +0 -0
  123. /package/contracts/{sac-manager → oapps/sac-manager}/src/tests/sac_manager/set_authorized.rs +0 -0
@@ -0,0 +1,18 @@
1
+ use crate::tests::test_helper::{mock_auth, TestSetup};
2
+ use soroban_sdk::Address;
3
+
4
+ pub fn mock_clawback_auth(setup: &TestSetup, sender: &Address, from: &Address, amount: i128) {
5
+ mock_auth(&setup.env, &setup.sac_manager, sender, "clawback", (from, amount));
6
+ }
7
+
8
+ pub fn mock_set_authorized_auth(setup: &TestSetup, user: &Address, authorize: bool) {
9
+ mock_auth(&setup.env, &setup.sac_manager, &setup.owner, "set_authorized", (user, authorize));
10
+ }
11
+
12
+ pub fn mock_release_sac_admin_auth(setup: &TestSetup, new_admin: &Address) {
13
+ mock_auth(&setup.env, &setup.sac_manager, &setup.owner, "release_sac_admin", (new_admin,));
14
+ }
15
+
16
+ pub fn mock_set_minter_auth(setup: &TestSetup, minter: &Address, active: bool) {
17
+ mock_auth(&setup.env, &setup.sac_manager, &setup.owner, "set_minter", (minter, active));
18
+ }
@@ -0,0 +1,28 @@
1
+ //! View Functions Integration Tests
2
+
3
+ use crate::tests::test_helper::TestSetup;
4
+
5
+ // =========================================================================
6
+ // Core View Functions
7
+ // =========================================================================
8
+
9
+ #[test]
10
+ fn test_underlying_sac() {
11
+ let setup = TestSetup::new().build();
12
+ assert_eq!(setup.sac_manager_client.underlying_sac(), setup.sac);
13
+ }
14
+
15
+ #[test]
16
+ fn test_minters() {
17
+ let setup = TestSetup::new().build();
18
+ let minters = setup.sac_manager_client.minters();
19
+ assert_eq!(minters.len(), 1);
20
+ assert_eq!(minters.get(0), Some(setup.minter.clone()));
21
+ }
22
+
23
+ #[test]
24
+ fn test_minters_empty_when_not_set() {
25
+ let setup = TestSetup::new().with_empty_minters().build();
26
+ let minters = setup.sac_manager_client.minters();
27
+ assert_eq!(minters.len(), 0);
28
+ }
@@ -25,19 +25,12 @@ use soroban_sdk::{
25
25
  /// ```
26
26
  pub struct TestSetupBuilder {
27
27
  manager_as_sac_admin: bool,
28
- redistribution_enabled: bool,
29
- supply_control_enabled: bool,
30
- skip_oft_setup: bool,
28
+ skip_minters_setup: bool,
31
29
  }
32
30
 
33
31
  impl TestSetupBuilder {
34
32
  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
- }
33
+ Self { manager_as_sac_admin: false, skip_minters_setup: false }
41
34
  }
42
35
 
43
36
  /// Set the SacManager as SAC admin during setup.
@@ -46,22 +39,10 @@ impl TestSetupBuilder {
46
39
  self
47
40
  }
48
41
 
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;
42
+ /// Skip setting minters during setup.
43
+ /// Use this to test `set_minter` auth or mint when no minter is set.
44
+ pub fn with_empty_minters(mut self) -> Self {
45
+ self.skip_minters_setup = true;
65
46
  self
66
47
  }
67
48
 
@@ -71,26 +52,24 @@ impl TestSetupBuilder {
71
52
 
72
53
  let owner = Address::generate(&env);
73
54
  let oft = Address::generate(&env);
74
- let sc_manager = Address::generate(&env);
75
55
  let sac_contract = env.register_stellar_asset_contract_v2(owner.clone());
76
56
  let sac = sac_contract.address();
77
57
 
78
- let sac_manager =
79
- env.register(SacManager, (&sac, &owner, self.redistribution_enabled, self.supply_control_enabled));
58
+ let sac_manager = env.register(SacManager, (&sac, &owner));
80
59
  let sac_manager_client = SacManagerClient::new(&env, &sac_manager);
81
60
  let sac_client = StellarAssetClient::new(&env, &sac);
82
61
 
83
- if !self.skip_oft_setup {
62
+ if !self.skip_minters_setup {
84
63
  env.mock_auths(&[MockAuth {
85
64
  address: &owner,
86
65
  invoke: &MockAuthInvoke {
87
66
  contract: &sac_manager,
88
- fn_name: "set_oft_address",
89
- args: (&oft,).into_val(&env),
67
+ fn_name: "set_minter",
68
+ args: (oft.clone(), true).into_val(&env),
90
69
  sub_invokes: &[],
91
70
  },
92
71
  }]);
93
- sac_manager_client.set_oft_address(&oft);
72
+ sac_manager_client.set_minter(&oft, &true);
94
73
  }
95
74
 
96
75
  if self.manager_as_sac_admin {
@@ -106,22 +85,10 @@ impl TestSetupBuilder {
106
85
  sac_client.set_admin(&sac_manager);
107
86
  }
108
87
 
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
88
  // Clear mock auths so test starts with clean auth state
122
89
  env.mock_auths(&[]);
123
90
 
124
- TestSetup { env, owner, oft, sc_manager, sac, sac_contract, sac_manager, sac_manager_client, sac_client }
91
+ TestSetup { env, owner, minter: oft, sac, sac_contract, sac_manager, sac_manager_client, sac_client }
125
92
  }
126
93
  }
127
94
 
@@ -133,8 +100,8 @@ impl TestSetupBuilder {
133
100
  pub struct TestSetup<'a> {
134
101
  pub env: Env,
135
102
  pub owner: Address,
136
- pub oft: Address,
137
- pub sc_manager: Address,
103
+ /// Address used as a minter in default setup (in minters list).
104
+ pub minter: Address,
138
105
  pub sac: Address,
139
106
  pub sac_contract: StellarAssetContract,
140
107
  pub sac_manager: Address,
@@ -174,17 +141,7 @@ pub fn mock_auth<A: IntoVal<Env, soroban_sdk::Vec<Val>>>(
174
141
  }]);
175
142
  }
176
143
 
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`.
144
+ /// Mock auth for minter-originated `mint(to, amount, operation)`.
188
145
  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));
146
+ mock_auth(&setup.env, &setup.sac_manager, &setup.minter, "mint", (recipient, amount, &setup.minter));
190
147
  }
@@ -221,12 +221,16 @@ sequenceDiagram
221
221
 
222
222
  ## Stellar-specific considerations
223
223
 
224
- Two core differences between Soroban and EVM require protocol-level adaptations:
224
+ Several differences between Soroban and EVM require protocol-level adaptations:
225
225
 
226
226
  1. Stellar's variable-length address model differs from LayerZero's fixed
227
227
  bytes32 address abstraction
228
228
  2. Soroban's Time-To-Live (TTL)-based storage model requires active state
229
229
  maintenance, unlike EVM's persistent storage
230
+ 3. Soroban's 200-read-per-transaction storage limit makes the lazy inbound
231
+ nonce model susceptible to denial-of-service for certain OApps
232
+ 4. Soroban prohibits reentrancy, requiring alternative patterns for cross-contract
233
+ call flows
230
234
 
231
235
  ### Constraint 1: bytes32 address format mismatch
232
236
 
@@ -296,7 +300,47 @@ constraints may evolve.
296
300
  - Hard upper cap on extension targets (e.g., 1 year) to prevent excessive fees
297
301
  - TTL parameters can be permanently frozen once the ecosystem stabilizes
298
302
 
299
- ### Constraint 3: Reentrancy prohibition
303
+ ### Constraint 3: Storage read limits
304
+
305
+ Soroban enforces a hard limit of 200 persistent/temporary storage reads per
306
+ transaction. Under the lazy inbound nonce model used in EVM, the `inbound_nonce`
307
+ is not stored directly — it is computed on the fly by iterating forward from the
308
+ last checkpoint (`lazy_inbound_nonce`) and probing storage for each consecutive
309
+ payload hash. The same iterative check occurs during `clear`, which must verify
310
+ that all nonces between the checkpoint and the target nonce have been verified.
311
+
312
+ For certain OApps, failed `lz_receive` executions can create nonce gaps that
313
+ grow over time. Under the lazy model, clearing subsequent messages requires
314
+ iterating across these gaps, and the accumulated storage reads can exceed the
315
+ 200-read limit, making the messaging path susceptible to denial-of-service.
316
+
317
+ **Solution: Eager inbound nonce with pending nonce list (Solana model)**
318
+
319
+ Stellar adopts the same inbound nonce model used by LayerZero V2 on Solana.
320
+ Instead of lazily computing the inbound nonce via storage probing, the
321
+ `inbound_nonce` is stored directly and updated eagerly during verification:
322
+
323
+ 1. **`PendingInboundNonces`**: A sorted list of out-of-order verified nonces is
324
+ maintained in a single storage entry per path. When a message is verified
325
+ (or skipped/nilified), its nonce is inserted into this list.
326
+
327
+ 2. **Drain on insert**: After each insertion, consecutive nonces at the front of
328
+ the list are drained to advance the `inbound_nonce`. For example, if
329
+ `inbound_nonce = 3` and the pending list becomes `[4, 5, 7]`, nonces 4 and 5
330
+ are drained, advancing `inbound_nonce` to 5.
331
+
332
+ 3. **O(1) clear**: The `clear_payload` operation becomes a simple comparison
333
+ (`nonce <= inbound_nonce`) with no iteration or storage probing.
334
+
335
+ 4. **Bounded list size**: The pending list is capped at 256 entries
336
+ (`PENDING_INBOUND_NONCE_MAX_LEN`). Nonces beyond `inbound_nonce + 256`
337
+ cannot be verified, preventing unbounded memory growth and limiting the
338
+ maximum storage reads per verify operation.
339
+
340
+ This eliminates the iterative storage reads that could cause DoS under the lazy
341
+ model, keeping all operations within Soroban's transaction resource limits.
342
+
343
+ ### Constraint 4: Reentrancy prohibition
300
344
 
301
345
  Soroban prohibits reentrancy—a contract cannot call itself, directly or
302
346
  indirectly, within the same transaction. This fundamental difference from EVM
package/package.json CHANGED
@@ -1,18 +1,23 @@
1
1
  {
2
2
  "name": "@layerzerolabs/protocol-stellar-v2",
3
- "version": "0.2.33",
3
+ "version": "0.2.35",
4
4
  "private": false,
5
5
  "devDependencies": {
6
6
  "@types/node": "^22.18.6",
7
7
  "tsx": "^4.19.3",
8
8
  "typescript": "^5.8.2",
9
- "@layerzerolabs/common-node-utils": "0.2.33",
10
- "@layerzerolabs/vm-tooling-stellar": "0.2.33"
9
+ "@layerzerolabs/common-node-utils": "0.2.35",
10
+ "@layerzerolabs/vm-tooling-stellar": "0.2.35"
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "restricted",
14
14
  "registry": "https://registry.npmjs.org/"
15
15
  },
16
+ "externalRepoConfig": {
17
+ "targets": [
18
+ "audit-external"
19
+ ]
20
+ },
16
21
  "scripts": {
17
22
  "build": "pnpm build:contracts && pnpm generate:sdk",
18
23
  "build:contracts": "pnpm exec lz-tool stellar contract build",