@layerzerolabs/protocol-stellar-v2 0.2.10 → 0.2.12

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 (129) hide show
  1. package/.turbo/turbo-build.log +273 -219
  2. package/.turbo/turbo-lint.log +79 -107
  3. package/.turbo/turbo-test.log +1016 -840
  4. package/Cargo.lock +14 -6
  5. package/contracts/common-macros/src/contract_impl.rs +6 -3
  6. package/contracts/common-macros/src/error.rs +9 -17
  7. package/contracts/common-macros/src/lib.rs +4 -37
  8. package/contracts/common-macros/src/ownable.rs +9 -5
  9. package/contracts/common-macros/src/tests/contract_impl.rs +178 -86
  10. package/contracts/common-macros/src/tests/error.rs +168 -0
  11. package/contracts/common-macros/src/tests/mod.rs +2 -4
  12. package/contracts/common-macros/src/tests/ownable.rs +37 -60
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap +16 -6
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__error__snapshot_generated_contract_error_code.snap +20 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +3 -1
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap +12 -2
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +5 -1
  18. package/contracts/common-macros/src/tests/utils.rs +267 -0
  19. package/contracts/common-macros/src/ttl_configurable.rs +15 -12
  20. package/contracts/common-macros/src/utils.rs +35 -6
  21. package/contracts/endpoint-v2/src/endpoint_v2.rs +4 -4
  22. package/contracts/endpoint-v2/src/events.rs +40 -22
  23. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +2 -2
  24. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +2 -2
  25. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +2 -2
  26. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
  27. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +2 -2
  28. package/contracts/endpoint-v2/src/message_lib_manager.rs +3 -3
  29. package/contracts/endpoint-v2/src/messaging_channel.rs +1 -1
  30. package/contracts/endpoint-v2/src/messaging_composer.rs +1 -1
  31. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +4 -8
  32. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +3 -7
  33. package/contracts/message-libs/{block-message-lib → blocked-message-lib}/Cargo.toml +1 -1
  34. package/contracts/message-libs/treasury/src/events.rs +9 -6
  35. package/contracts/message-libs/uln-302/src/events.rs +19 -11
  36. package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +2 -2
  37. package/contracts/message-libs/uln-302/src/interfaces/send_uln.rs +2 -2
  38. package/contracts/message-libs/uln-302/src/receive_uln.rs +2 -2
  39. package/contracts/message-libs/uln-302/src/send_uln.rs +3 -3
  40. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +5 -5
  41. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +5 -5
  42. package/contracts/message-libs/uln-302/src/tests/setup.rs +3 -3
  43. package/contracts/message-libs/uln-302/src/types.rs +24 -24
  44. package/contracts/message-libs/uln-302/src/uln302.rs +2 -2
  45. package/contracts/oapp-macros/src/oapp_core.rs +1 -1
  46. package/contracts/oapps/counter/integration_tests/utils.rs +1 -1
  47. package/contracts/oapps/oapp/src/oapp_core.rs +4 -3
  48. package/contracts/oapps/oapp/src/oapp_options_type3.rs +4 -3
  49. package/contracts/oapps/oft/integration-tests/setup.rs +4 -3
  50. package/contracts/oapps/oft/integration-tests/utils.rs +1 -1
  51. package/contracts/oapps/oft/src/default_oft_impl.rs +146 -0
  52. package/contracts/oapps/oft/src/events.rs +5 -4
  53. package/contracts/oapps/oft/src/extensions/mod.rs +3 -0
  54. package/contracts/oapps/oft/src/extensions/oft_fee.rs +168 -0
  55. package/contracts/oapps/oft/src/extensions/pausable.rs +50 -0
  56. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +200 -0
  57. package/contracts/oapps/oft/src/lib.rs +2 -3
  58. package/contracts/oapps/oft/src/oft.rs +16 -85
  59. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -1
  60. package/contracts/oapps/oft/src/tests/extensions/mod.rs +11 -0
  61. package/contracts/oapps/oft/src/tests/extensions/setup.rs +888 -0
  62. package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +749 -0
  63. package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +432 -0
  64. package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +1078 -0
  65. package/contracts/oapps/oft/src/tests/mod.rs +2 -0
  66. package/contracts/oapps/oft/src/tests/test_utils.rs +24 -6
  67. package/contracts/oapps/{oft-mint-burn → oft-std}/Cargo.toml +1 -8
  68. package/contracts/oapps/oft-std/src/lib.rs +5 -0
  69. package/contracts/oapps/oft-std/src/oft.rs +59 -0
  70. package/contracts/utils/src/ownable.rs +8 -6
  71. package/contracts/utils/src/tests/ownable.rs +0 -63
  72. package/contracts/utils/src/tests/testing_utils.rs +7 -5
  73. package/contracts/utils/src/ttl.rs +21 -2
  74. package/contracts/workers/dvn/src/auth.rs +108 -30
  75. package/contracts/workers/dvn/src/dvn.rs +103 -33
  76. package/contracts/workers/dvn/src/errors.rs +10 -13
  77. package/contracts/workers/dvn/src/events.rs +7 -5
  78. package/contracts/workers/dvn/src/interfaces/dvn.rs +76 -3
  79. package/contracts/workers/dvn/src/interfaces/multisig.rs +41 -0
  80. package/contracts/workers/dvn/src/lib.rs +6 -8
  81. package/contracts/workers/dvn/src/multisig.rs +98 -72
  82. package/contracts/workers/dvn/src/storage.rs +9 -12
  83. package/contracts/workers/dvn/src/tests/auth.rs +56 -26
  84. package/contracts/workers/dvn/src/tests/dvn.rs +40 -41
  85. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +8 -8
  86. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +9 -9
  87. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +6 -6
  88. package/contracts/workers/dvn/src/tests/setup.rs +5 -5
  89. package/contracts/workers/dvn-fee-lib/Cargo.toml +2 -1
  90. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +4 -3
  91. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +8 -6
  92. package/contracts/workers/executor/src/auth.rs +93 -0
  93. package/contracts/workers/executor/src/events.rs +5 -4
  94. package/contracts/workers/executor/src/{lz_executor.rs → executor.rs} +30 -103
  95. package/contracts/workers/executor/src/interfaces/executor.rs +5 -2
  96. package/contracts/workers/executor/src/interfaces/mod.rs +1 -1
  97. package/contracts/workers/executor/src/lib.rs +6 -5
  98. package/contracts/workers/price-feed/Cargo.toml +21 -0
  99. package/contracts/workers/price-feed/src/errors.rs +9 -0
  100. package/contracts/workers/price-feed/src/events.rs +30 -0
  101. package/contracts/workers/price-feed/src/lib.rs +11 -0
  102. package/contracts/workers/price-feed/src/price_feed.rs +265 -0
  103. package/contracts/workers/price-feed/src/storage.rs +42 -0
  104. package/contracts/workers/price-feed/src/types.rs +59 -0
  105. package/contracts/workers/worker/src/events.rs +23 -13
  106. package/contracts/workers/worker/src/interfaces/dvn_fee_lib.rs +2 -1
  107. package/contracts/workers/worker/src/worker.rs +32 -21
  108. package/package.json +3 -3
  109. package/sdk/dist/generated/bml.js +24 -22
  110. package/sdk/dist/generated/counter.d.ts +102 -0
  111. package/sdk/dist/generated/counter.js +36 -24
  112. package/sdk/dist/generated/endpoint.js +24 -22
  113. package/sdk/dist/generated/sml.js +24 -22
  114. package/sdk/dist/generated/uln302.d.ts +1 -1
  115. package/sdk/dist/generated/uln302.js +34 -32
  116. package/sdk/package.json +1 -1
  117. package/sdk/test/index.test.ts +1 -1
  118. package/sdk/test/oft.test.ts +847 -0
  119. package/sdk/test/suites/scan.ts +20 -4
  120. package/tools/ts-bindings-gen/src/main.rs +2 -1
  121. package/contracts/common-macros/src/event.rs +0 -16
  122. package/contracts/oapps/oft/src/macro_tests/mod.rs +0 -2
  123. package/contracts/oapps/oft/src/macro_tests/test_all_default.rs +0 -41
  124. package/contracts/oapps/oft/src/macro_tests/test_override.rs +0 -83
  125. package/contracts/oapps/oft-mint-burn/src/lib.rs +0 -3
  126. package/contracts/oapps/oft-mint-burn/src/oft.rs +0 -28
  127. package/contracts/oapps/oft-mint-burn/src/tests/mod.rs +0 -1
  128. package/contracts/workers/dvn/src/types.rs +0 -26
  129. /package/contracts/message-libs/{block-message-lib → blocked-message-lib}/src/lib.rs +0 -0
@@ -1,5 +1,5 @@
1
1
  use crate::tests::setup::TestSetup;
2
- use crate::{dvn::Dvn, DVNClient, DstConfig, DstConfigParam, IDVN};
2
+ use crate::{dvn::LzDVN, DVNClient, DstConfig, DstConfigParam, IDVN};
3
3
  use endpoint_v2::FeeRecipient;
4
4
  use message_lib_common::interfaces::ILayerZeroDVN;
5
5
  use soroban_sdk::{
@@ -22,7 +22,7 @@ fn new_addr(env: &Env) -> Address {
22
22
 
23
23
  fn grant_allowlist(setup: &TestSetup, oapp: &Address) {
24
24
  with_contract(setup, || {
25
- Dvn::set_allowlist(&setup.env, oapp, true);
25
+ LzDVN::set_allowlist(&setup.env, oapp, true);
26
26
  });
27
27
  }
28
28
 
@@ -30,17 +30,17 @@ fn configure_dst_config(setup: &TestSetup, dst_eid: u32, config: DstConfig) {
30
30
  let admin = setup.admins.get(0).unwrap();
31
31
  let params = vec![&setup.env, DstConfigParam { dst_eid, config }];
32
32
  with_contract(setup, || {
33
- Dvn::set_dst_config(&setup.env, &admin, &params);
33
+ LzDVN::set_dst_config(&setup.env, &admin, &params);
34
34
  });
35
35
  }
36
36
 
37
37
  fn configure_fee_lib(setup: &TestSetup, fee_lib: &Address, default_multiplier: u32) {
38
38
  let admin = setup.admins.get(0).unwrap();
39
39
  with_contract(setup, || {
40
- Dvn::set_worker_fee_lib(&setup.env, &admin, fee_lib);
40
+ LzDVN::set_worker_fee_lib(&setup.env, &admin, fee_lib);
41
41
  });
42
42
  with_contract(setup, || {
43
- Dvn::set_default_multiplier_bps(&setup.env, &admin, default_multiplier);
43
+ LzDVN::set_default_multiplier_bps(&setup.env, &admin, default_multiplier);
44
44
  });
45
45
  }
46
46
 
@@ -52,15 +52,14 @@ fn test_vid_returns_configured_value() {
52
52
  }
53
53
 
54
54
  #[test]
55
- #[should_panic(expected = "Error(Contract, #5)")] // DvnError::EidNotSupported
56
- fn test_dst_config_not_set_panics() {
55
+ fn test_dst_config_not_set_returns_none() {
57
56
  let setup = TestSetup::new(1);
58
57
  let client = DVNClient::new(&setup.env, &setup.contract_id);
59
- client.dst_config(&999);
58
+ assert_eq!(client.dst_config(&999), None);
60
59
  }
61
60
 
62
61
  #[test]
63
- #[should_panic(expected = "Error(Contract, #5)")] // DvnError::EidNotSupported
62
+ #[should_panic(expected = "Error(Contract, #2)")] // DvnError::EidNotSupported
64
63
  fn test_get_fee_missing_dst_config_panics() {
65
64
  let setup = TestSetup::new(1);
66
65
  let send_lib = new_addr(&setup.env);
@@ -70,7 +69,7 @@ fn test_get_fee_missing_dst_config_panics() {
70
69
  let options = Bytes::new(&setup.env);
71
70
 
72
71
  with_contract(&setup, || {
73
- Dvn::get_fee(&setup.env, &send_lib, &sender, 999, &packet_header, &payload_hash, 1, &options);
72
+ LzDVN::get_fee(&setup.env, &send_lib, &sender, 999, &packet_header, &payload_hash, 1, &options);
74
73
  });
75
74
  }
76
75
 
@@ -88,7 +87,7 @@ fn test_get_fee_not_allowed_due_to_allowlist() {
88
87
  let options = Bytes::new(&setup.env);
89
88
 
90
89
  with_contract(&setup, || {
91
- Dvn::get_fee(&setup.env, &send_lib, &sender, 1, &packet_header, &payload_hash, 1, &options);
90
+ LzDVN::get_fee(&setup.env, &send_lib, &sender, 1, &packet_header, &payload_hash, 1, &options);
92
91
  });
93
92
  }
94
93
 
@@ -100,7 +99,7 @@ fn test_get_fee_uses_default_multiplier_when_dst_multiplier_zero() {
100
99
  configure_dst_config(&setup, 42, DstConfig { gas: 1, multiplier_bps: 0, floor_margin_usd: 0 });
101
100
 
102
101
  let fee = with_contract(&setup, || {
103
- Dvn::get_fee(
102
+ LzDVN::get_fee(
104
103
  &setup.env,
105
104
  &new_addr(&setup.env),
106
105
  &new_addr(&setup.env),
@@ -123,7 +122,7 @@ fn test_get_fee_prefers_dst_multiplier_when_nonzero() {
123
122
  configure_dst_config(&setup, 43, DstConfig { gas: 1, multiplier_bps: 9_000, floor_margin_usd: 0 });
124
123
 
125
124
  let fee = with_contract(&setup, || {
126
- Dvn::get_fee(
125
+ LzDVN::get_fee(
127
126
  &setup.env,
128
127
  &new_addr(&setup.env),
129
128
  &new_addr(&setup.env),
@@ -145,54 +144,54 @@ fn test_pause_and_setters_happy_paths() {
145
144
  let other = new_addr(&setup.env);
146
145
 
147
146
  with_contract(&setup, || {
148
- Dvn::set_paused(&setup.env, true);
147
+ LzDVN::set_paused(&setup.env, true);
149
148
  });
150
149
  with_contract(&setup, || {
151
- assert!(Dvn::paused(&setup.env));
150
+ assert!(LzDVN::paused(&setup.env));
152
151
  });
153
152
  with_contract(&setup, || {
154
- Dvn::set_paused(&setup.env, false);
153
+ LzDVN::set_paused(&setup.env, false);
155
154
  });
156
155
  with_contract(&setup, || {
157
- assert!(!Dvn::paused(&setup.env));
156
+ assert!(!LzDVN::paused(&setup.env));
158
157
  });
159
158
 
160
159
  with_contract(&setup, || {
161
- Dvn::set_default_multiplier_bps(&setup.env, &admin, 1234);
160
+ LzDVN::set_default_multiplier_bps(&setup.env, &admin, 1234);
162
161
  });
163
162
  with_contract(&setup, || {
164
- assert_eq!(Dvn::default_multiplier_bps(&setup.env), 1234);
163
+ assert_eq!(LzDVN::default_multiplier_bps(&setup.env), 1234);
165
164
  });
166
165
 
167
166
  with_contract(&setup, || {
168
- Dvn::set_deposit_address(&setup.env, &admin, &other);
167
+ LzDVN::set_deposit_address(&setup.env, &admin, &other);
169
168
  });
170
169
  with_contract(&setup, || {
171
- assert_eq!(Dvn::deposit_address(&setup.env), other);
170
+ assert_eq!(LzDVN::deposit_address(&setup.env), other);
172
171
  });
173
172
 
174
173
  let pf = new_addr(&setup.env);
175
174
  with_contract(&setup, || {
176
- Dvn::set_price_feed(&setup.env, &admin, &pf);
175
+ LzDVN::set_price_feed(&setup.env, &admin, &pf);
177
176
  });
178
177
  with_contract(&setup, || {
179
- assert_eq!(Dvn::price_feed(&setup.env), pf);
178
+ assert_eq!(LzDVN::price_feed(&setup.env), pf);
180
179
  });
181
180
 
182
181
  let opts = Bytes::from_array(&setup.env, &[1, 2, 3]);
183
182
  with_contract(&setup, || {
184
- Dvn::set_supported_option_types(&setup.env, &admin, 77, opts.clone());
183
+ LzDVN::set_supported_option_types(&setup.env, &admin, 77, opts.clone());
185
184
  });
186
185
  with_contract(&setup, || {
187
- assert_eq!(Dvn::get_supported_option_types(&setup.env, 77), Some(opts));
186
+ assert_eq!(LzDVN::get_supported_option_types(&setup.env, 77), Some(opts));
188
187
  });
189
188
 
190
189
  let fee_lib = new_addr(&setup.env);
191
190
  with_contract(&setup, || {
192
- Dvn::set_worker_fee_lib(&setup.env, &admin, &fee_lib);
191
+ LzDVN::set_worker_fee_lib(&setup.env, &admin, &fee_lib);
193
192
  });
194
193
  with_contract(&setup, || {
195
- assert_eq!(Dvn::worker_fee_lib(&setup.env), fee_lib);
194
+ assert_eq!(LzDVN::worker_fee_lib(&setup.env), fee_lib);
196
195
  });
197
196
  }
198
197
 
@@ -201,9 +200,9 @@ fn test_acl_and_allowlist_size_reads() {
201
200
  let setup = TestSetup::new(1);
202
201
  let addr = setup.admins.get(0).unwrap();
203
202
 
204
- let has_acl = with_contract(&setup, || Dvn::has_acl(&setup.env, &addr));
203
+ let has_acl = with_contract(&setup, || LzDVN::has_acl(&setup.env, &addr));
205
204
  assert!(has_acl);
206
- let allowlist_size = with_contract(&setup, || Dvn::allowlist_size(&setup.env));
205
+ let allowlist_size = with_contract(&setup, || LzDVN::allowlist_size(&setup.env));
207
206
  assert_eq!(allowlist_size, 0);
208
207
  }
209
208
 
@@ -251,14 +250,14 @@ fn test_assign_job_auth_verification() {
251
250
  configure_dst_config(&setup, dst_eid, DstConfig { gas: 1, multiplier_bps: 10_000, floor_margin_usd: 0 });
252
251
 
253
252
  with_contract(&setup, || {
254
- Dvn::set_deposit_address(&setup.env, &admin, &deposit_addr);
253
+ LzDVN::set_deposit_address(&setup.env, &admin, &deposit_addr);
255
254
  });
256
255
  with_contract(&setup, || {
257
- Dvn::set_supported_message_lib(&setup.env, &send_lib, true);
256
+ LzDVN::set_supported_message_lib(&setup.env, &send_lib, true);
258
257
  });
259
258
 
260
259
  let result = setup.env.as_contract(&setup.contract_id, || {
261
- Dvn::assign_job(&setup.env, &send_lib, &sender, dst_eid, &packet_header, &payload_hash, 1, &options)
260
+ LzDVN::assign_job(&setup.env, &send_lib, &sender, dst_eid, &packet_header, &payload_hash, 1, &options)
262
261
  });
263
262
 
264
263
  assert_eq!(result, FeeRecipient { amount: 10_000, to: deposit_addr.clone() });
@@ -275,16 +274,16 @@ fn test_set_admin_add() {
275
274
  let new_admin = new_addr(&setup.env);
276
275
 
277
276
  // Verify new_admin is not an admin initially
278
- let is_admin = with_contract(&setup, || Dvn::is_admin(&setup.env, &new_admin));
277
+ let is_admin = with_contract(&setup, || LzDVN::is_admin(&setup.env, &new_admin));
279
278
  assert!(!is_admin);
280
279
 
281
280
  // Add new admin by existing admin
282
281
  with_contract(&setup, || {
283
- Dvn::set_admin(&setup.env, &existing_admin, &new_admin, true);
282
+ LzDVN::set_admin(&setup.env, &existing_admin, &new_admin, true);
284
283
  });
285
284
 
286
285
  // Verify new_admin is now an admin
287
- let is_admin = with_contract(&setup, || Dvn::is_admin(&setup.env, &new_admin));
286
+ let is_admin = with_contract(&setup, || LzDVN::is_admin(&setup.env, &new_admin));
288
287
  assert!(is_admin);
289
288
  }
290
289
 
@@ -296,16 +295,16 @@ fn test_set_admin_remove() {
296
295
 
297
296
  // Add new admin first
298
297
  with_contract(&setup, || {
299
- Dvn::set_admin(&setup.env, &existing_admin, &new_admin, true);
298
+ LzDVN::set_admin(&setup.env, &existing_admin, &new_admin, true);
300
299
  });
301
300
 
302
301
  // Remove the new admin
303
302
  with_contract(&setup, || {
304
- Dvn::set_admin(&setup.env, &existing_admin, &new_admin, false);
303
+ LzDVN::set_admin(&setup.env, &existing_admin, &new_admin, false);
305
304
  });
306
305
 
307
306
  // Verify new_admin is no longer an admin
308
- let is_admin = with_contract(&setup, || Dvn::is_admin(&setup.env, &new_admin));
307
+ let is_admin = with_contract(&setup, || LzDVN::is_admin(&setup.env, &new_admin));
309
308
  assert!(!is_admin);
310
309
  }
311
310
 
@@ -318,7 +317,7 @@ fn test_set_admin_unauthorized() {
318
317
 
319
318
  // Attempt to add admin by non-admin should fail
320
319
  with_contract(&setup, || {
321
- Dvn::set_admin(&setup.env, &non_admin, &new_admin, true);
320
+ LzDVN::set_admin(&setup.env, &non_admin, &new_admin, true);
322
321
  });
323
322
  }
324
323
 
@@ -330,7 +329,7 @@ fn test_set_admin_cannot_remove_last_admin() {
330
329
 
331
330
  // Attempt to remove the only admin should fail
332
331
  with_contract(&setup, || {
333
- Dvn::set_admin(&setup.env, &existing_admin, &existing_admin, false);
332
+ LzDVN::set_admin(&setup.env, &existing_admin, &existing_admin, false);
334
333
  });
335
334
  }
336
335
 
@@ -339,7 +338,7 @@ struct MockFeeLib;
339
338
 
340
339
  #[contractimpl]
341
340
  impl IDvnFeeLib for MockFeeLib {
342
- fn get_fee(_env: &Env, params: &DvnFeeParams) -> i128 {
341
+ fn get_fee(_env: &Env, _dvn: &Address, params: &DvnFeeParams) -> i128 {
343
342
  if params.multiplier_bps == 0 {
344
343
  params.default_multiplier_bps as i128
345
344
  } else {
@@ -1,5 +1,5 @@
1
- use crate::errors::MultisigError;
2
- use crate::storage::MultisigStorage;
1
+ use crate::errors::DvnError;
2
+ use crate::storage::DvnStorage;
3
3
  use crate::tests::setup::TestSetup;
4
4
  use soroban_sdk::{
5
5
  testutils::{AuthorizedFunction, BytesN as _},
@@ -12,7 +12,7 @@ fn random_signer(env: &Env) -> BytesN<20> {
12
12
 
13
13
  fn clear_signers(setup: &TestSetup) {
14
14
  setup.env.as_contract(&setup.contract_id, || {
15
- MultisigStorage::remove_signers(&setup.env);
15
+ DvnStorage::remove_signers(&setup.env);
16
16
  });
17
17
  }
18
18
 
@@ -48,7 +48,7 @@ fn test_set_signer_duplicate_fails() {
48
48
  setup.multisig_client.set_signer(&signer, &true);
49
49
  let res = setup.multisig_client.try_set_signer(&signer, &true);
50
50
 
51
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::SignerAlreadyExists.into());
51
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::SignerAlreadyExists.into());
52
52
  }
53
53
 
54
54
  #[test]
@@ -69,7 +69,7 @@ fn test_set_signer_remove_not_found() {
69
69
  let signer = random_signer(&setup.env);
70
70
 
71
71
  let res = setup.multisig_client.try_set_signer(&signer, &false);
72
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::SignerNotFound.into());
72
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::SignerNotFound.into());
73
73
  }
74
74
 
75
75
  #[test]
@@ -78,7 +78,7 @@ fn test_set_signer_invalid_signer_zero_address() {
78
78
  let zero = BytesN::from_array(&setup.env, &[0u8; 20]);
79
79
 
80
80
  let res = setup.multisig_client.try_set_signer(&zero, &true);
81
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::InvalidSigner.into());
81
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::InvalidSigner.into());
82
82
  }
83
83
 
84
84
  #[test]
@@ -115,7 +115,7 @@ fn test_remove_signer_when_no_signers() {
115
115
 
116
116
  let signer = random_signer(&setup.env);
117
117
  let res = setup.multisig_client.try_set_signer(&signer, &false);
118
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::SignerNotFound.into());
118
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::SignerNotFound.into());
119
119
  }
120
120
 
121
121
  #[test]
@@ -129,5 +129,5 @@ fn test_remove_signer_violates_threshold() {
129
129
 
130
130
  // Removing a signer should fail because it would leave only 1 signer with threshold 2
131
131
  let res = setup.multisig_client.try_set_signer(&signer_to_remove, &false);
132
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::TotalSignersLessThanThreshold.into());
132
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::TotalSignersLessThanThreshold.into());
133
133
  }
@@ -1,5 +1,5 @@
1
1
  use crate::tests::setup::{TestSetup, DEFAULT_MULTIPLIER_BPS, VID};
2
- use crate::{dvn::Dvn, errors::MultisigError, storage::MultisigStorage};
2
+ use crate::{dvn::LzDVN, errors::DvnError, storage::DvnStorage};
3
3
  use soroban_sdk::{
4
4
  testutils::{Address as _, AuthorizedFunction, BytesN as _},
5
5
  vec, Address, BytesN, Env, IntoVal, Symbol, Vec,
@@ -21,7 +21,7 @@ fn register_dvn(env: &Env, signer_count: usize, threshold: u32) {
21
21
  let deposit_address: Address = Address::generate(env);
22
22
 
23
23
  let _ = env.register(
24
- Dvn,
24
+ LzDVN,
25
25
  (
26
26
  &VID,
27
27
  &signers,
@@ -29,8 +29,8 @@ fn register_dvn(env: &Env, signer_count: usize, threshold: u32) {
29
29
  &admins,
30
30
  &supported_msglibs,
31
31
  &price_feed,
32
- &worker_fee_lib,
33
32
  &DEFAULT_MULTIPLIER_BPS,
33
+ &worker_fee_lib,
34
34
  &deposit_address,
35
35
  ),
36
36
  );
@@ -66,7 +66,7 @@ fn test_set_threshold_zero_fails() {
66
66
  let setup = TestSetup::new(1);
67
67
 
68
68
  let res = setup.multisig_client.try_set_threshold(&0);
69
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::ZeroThreshold.into());
69
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::ZeroThreshold.into());
70
70
  }
71
71
 
72
72
  #[test]
@@ -74,7 +74,7 @@ fn test_set_threshold_above_signers_fails() {
74
74
  let setup = TestSetup::new(2);
75
75
 
76
76
  let res = setup.multisig_client.try_set_threshold(&3);
77
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::TotalSignersLessThanThreshold.into());
77
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::TotalSignersLessThanThreshold.into());
78
78
  }
79
79
 
80
80
  #[test]
@@ -82,15 +82,15 @@ fn test_set_threshold_with_no_signers_fails() {
82
82
  let setup = TestSetup::new(1);
83
83
 
84
84
  setup.env.as_contract(&setup.contract_id, || {
85
- MultisigStorage::remove_signers(&setup.env);
85
+ DvnStorage::remove_signers(&setup.env);
86
86
  });
87
87
 
88
88
  let res = setup.multisig_client.try_set_threshold(&1);
89
- assert_eq!(res.err().unwrap().ok().unwrap(), MultisigError::TotalSignersLessThanThreshold.into());
89
+ assert_eq!(res.err().unwrap().ok().unwrap(), DvnError::TotalSignersLessThanThreshold.into());
90
90
  }
91
91
 
92
92
  #[test]
93
- #[should_panic(expected = "Error(Contract, #1)")] // MultisigError::ZeroThreshold
93
+ #[should_panic(expected = "Error(Contract, #13)")] // DvnError::ZeroThreshold
94
94
  fn test_constructor_threshold_zero_panics() {
95
95
  let env = Env::default();
96
96
  env.mock_all_auths();
@@ -99,7 +99,7 @@ fn test_constructor_threshold_zero_panics() {
99
99
  }
100
100
 
101
101
  #[test]
102
- #[should_panic(expected = "Error(Contract, #2)")] // MultisigError::TotalSignersLessThanThreshold
102
+ #[should_panic(expected = "Error(Contract, #11)")] // DvnError::TotalSignersLessThanThreshold
103
103
  fn test_constructor_signers_less_than_threshold_panics() {
104
104
  let env = Env::default();
105
105
  env.mock_all_auths();
@@ -1,6 +1,6 @@
1
1
  extern crate std;
2
2
 
3
- use crate::storage::MultisigStorage;
3
+ use crate::storage::DvnStorage;
4
4
  use crate::tests::key_pair::KeyPair;
5
5
  use crate::tests::setup::TestSetup;
6
6
  use soroban_sdk::{vec, Bytes, BytesN, Vec};
@@ -59,7 +59,7 @@ fn test_verify_signatures_raw_v_path() {
59
59
  }
60
60
 
61
61
  #[test]
62
- #[should_panic(expected = "Error(Contract, #5)")] // MultisigError::SignerNotFound
62
+ #[should_panic(expected = "Error(Contract, #10)")] // DvnError::SignerNotFound
63
63
  fn test_verify_signatures_with_wrong_signer() {
64
64
  let setup = TestSetup::new(1);
65
65
  let digest = hash(&setup.env, b"test");
@@ -71,7 +71,7 @@ fn test_verify_signatures_with_wrong_signer() {
71
71
  }
72
72
 
73
73
  #[test]
74
- #[should_panic(expected = "Error(Contract, #7)")] // MultisigError::SignatureError
74
+ #[should_panic(expected = "Error(Contract, #8)")] // DvnError::SignatureError
75
75
  fn test_verify_signatures_insufficient_signatures() {
76
76
  let setup = TestSetup::new(2);
77
77
  let digest = hash(&setup.env, b"insufficient");
@@ -82,7 +82,7 @@ fn test_verify_signatures_insufficient_signatures() {
82
82
  }
83
83
 
84
84
  #[test]
85
- #[should_panic(expected = "Error(Contract, #6)")] // MultisigError::UnsortedSigners
85
+ #[should_panic(expected = "Error(Contract, #12)")] // DvnError::UnsortedSigners
86
86
  fn test_verify_signatures_duplicate_signer() {
87
87
  let setup = TestSetup::new(2);
88
88
  let digest = hash(&setup.env, b"duplicate");
@@ -94,12 +94,12 @@ fn test_verify_signatures_duplicate_signer() {
94
94
  }
95
95
 
96
96
  #[test]
97
- #[should_panic(expected = "Error(Contract, #1)")] // MultisigError::ZeroThreshold
97
+ #[should_panic(expected = "Error(Contract, #13)")] // DvnError::ZeroThreshold
98
98
  fn test_verify_signatures_threshold_zero() {
99
99
  let setup = TestSetup::new(1);
100
100
  // Force threshold to 0 via storage to hit ZeroThreshold branch
101
101
  setup.env.as_contract(&setup.contract_id, || {
102
- MultisigStorage::set_threshold(&setup.env, &0);
102
+ DvnStorage::set_threshold(&setup.env, &0);
103
103
  });
104
104
  let digest = hash(&setup.env, b"threshold_zero");
105
105
 
@@ -3,7 +3,7 @@
3
3
  extern crate std;
4
4
 
5
5
  use crate::tests::key_pair::KeyPair;
6
- use crate::{dvn::Dvn, interfaces::MultiSigClient};
6
+ use crate::{dvn::LzDVN, interfaces::MultiSigClient};
7
7
  use soroban_sdk::{address_payload::AddressPayload, testutils::Address as _, vec, Address, BytesN, Env, Vec};
8
8
  use std::vec::Vec as StdVec;
9
9
 
@@ -44,7 +44,7 @@ impl<'a> TestSetup<'a> {
44
44
  let deposit_address: Address = Address::generate(&env);
45
45
 
46
46
  let contract_id = env.register(
47
- Dvn,
47
+ LzDVN,
48
48
  (
49
49
  &VID,
50
50
  &signers,
@@ -52,8 +52,8 @@ impl<'a> TestSetup<'a> {
52
52
  &admins,
53
53
  &supported_msglibs,
54
54
  &price_feed,
55
- &worker_fee_lib,
56
55
  &DEFAULT_MULTIPLIER_BPS,
56
+ &worker_fee_lib,
57
57
  &deposit_address,
58
58
  ),
59
59
  );
@@ -88,7 +88,7 @@ impl<'a> TestSetup<'a> {
88
88
  let deposit_address: Address = Address::generate(&env);
89
89
 
90
90
  let contract_id = env.register(
91
- Dvn,
91
+ LzDVN,
92
92
  (
93
93
  &VID,
94
94
  &signers,
@@ -96,8 +96,8 @@ impl<'a> TestSetup<'a> {
96
96
  &admins,
97
97
  &supported_msglibs,
98
98
  &price_feed,
99
- &worker_fee_lib,
100
99
  &DEFAULT_MULTIPLIER_BPS,
100
+ &worker_fee_lib,
101
101
  &deposit_address,
102
102
  ),
103
103
  );
@@ -16,9 +16,10 @@ doctest = false
16
16
  [dependencies]
17
17
  cfg-if = "1.0"
18
18
  soroban-sdk = { workspace = true }
19
+ common-macros = { workspace = true }
19
20
  message-lib-common = { workspace = true }
21
+ utils = { workspace = true }
20
22
  worker = { workspace = true }
21
- common-macros = { workspace = true }
22
23
 
23
24
  [dev-dependencies]
24
25
  soroban-sdk = { workspace = true, features = ["testutils"] }
@@ -1,5 +1,6 @@
1
1
  use crate::DvnFeeLibError;
2
- use soroban_sdk::{assert_with_error, contract, contractimpl, Env};
2
+ use common_macros::contract_impl;
3
+ use soroban_sdk::{assert_with_error, contract, Address, Env};
3
4
  use worker::{DvnFeeParams, IDvnFeeLib, LayerZeroPriceFeedClient};
4
5
 
5
6
  // ============================================================================
@@ -29,9 +30,9 @@ pub(crate) const NATIVE_DECIMALS_RATE: u128 = 10_000_000;
29
30
  #[contract]
30
31
  pub struct DvnFeeLib;
31
32
 
32
- #[contractimpl]
33
+ #[contract_impl]
33
34
  impl IDvnFeeLib for DvnFeeLib {
34
- fn get_fee(env: &Env, params: &DvnFeeParams) -> i128 {
35
+ fn get_fee(env: &Env, _dvn: &Address, params: &DvnFeeParams) -> i128 {
35
36
  assert_with_error!(env, params.gas > 0, DvnFeeLibError::InvalidGas);
36
37
  assert_with_error!(env, params.options.is_empty(), DvnFeeLibError::InvalidDVNOptions);
37
38
 
@@ -77,6 +77,7 @@ fn apply_premium_multiplier_wins_over_small_floor() {
77
77
  fn get_fee_panics_when_gas_zero() {
78
78
  let env = Env::default();
79
79
  env.mock_all_auths();
80
+ let fee_lib_addr = env.register(DvnFeeLib, ());
80
81
  let params = DvnFeeParams {
81
82
  sender: Address::generate(&env),
82
83
  dst_eid: 1,
@@ -90,7 +91,7 @@ fn get_fee_panics_when_gas_zero() {
90
91
  floor_margin_usd: 0,
91
92
  };
92
93
 
93
- DvnFeeLib::get_fee(&env, &params);
94
+ env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &fee_lib_addr, &params));
94
95
  }
95
96
 
96
97
  #[test]
@@ -98,6 +99,7 @@ fn get_fee_panics_when_gas_zero() {
98
99
  fn get_fee_panics_when_options_not_empty() {
99
100
  let env = Env::default();
100
101
  env.mock_all_auths();
102
+ let fee_lib_addr = env.register(DvnFeeLib, ());
101
103
  let mut options = Bytes::new(&env);
102
104
  options.push_back(1u8);
103
105
 
@@ -114,7 +116,7 @@ fn get_fee_panics_when_options_not_empty() {
114
116
  floor_margin_usd: 0,
115
117
  };
116
118
 
117
- DvnFeeLib::get_fee(&env, &params);
119
+ env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &fee_lib_addr, &params));
118
120
  }
119
121
 
120
122
  #[contract]
@@ -183,7 +185,7 @@ fn get_fee_success_path() {
183
185
  floor_margin_usd: 0,
184
186
  };
185
187
 
186
- let fee = env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &params));
188
+ let fee = env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &fee_lib_addr, &params));
187
189
 
188
190
  assert_eq!(fee, 100);
189
191
  }
@@ -209,7 +211,7 @@ fn get_fee_uses_default_multiplier_when_zero() {
209
211
  floor_margin_usd: 0,
210
212
  };
211
213
 
212
- let fee = env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &params));
214
+ let fee = env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &fee_lib_addr, &params));
213
215
 
214
216
  assert_eq!(fee, 120);
215
217
  }
@@ -235,7 +237,7 @@ fn get_fee_prefers_dst_multiplier_over_default() {
235
237
  floor_margin_usd: 0,
236
238
  };
237
239
 
238
- let fee = env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &params));
240
+ let fee = env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &fee_lib_addr, &params));
239
241
 
240
242
  assert_eq!(fee, 150);
241
243
  }
@@ -259,7 +261,7 @@ fn get_fee_panics_when_price_feed_returns_negative_fee() {
259
261
  floor_margin_usd: 0,
260
262
  };
261
263
 
262
- env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &params));
264
+ env.as_contract(&fee_lib_addr, || DvnFeeLib::get_fee(&env, &fee_lib_addr, &params));
263
265
  }
264
266
 
265
267
  #[test]
@@ -0,0 +1,93 @@
1
+ use super::*;
2
+
3
+ use soroban_sdk::{
4
+ address_payload::AddressPayload,
5
+ auth::{Context, CustomAccountInterface},
6
+ contractimpl, contracttype,
7
+ crypto::Hash,
8
+ };
9
+
10
+ // ============================================================================
11
+ // Authentication Data Types
12
+ // ============================================================================
13
+
14
+ /// Signature data for Custom Account authorization.
15
+ /// Contains the admin's public key and their Ed25519 signature over the authorization payload.
16
+ #[contracttype]
17
+ #[derive(Clone, Debug, Eq, PartialEq)]
18
+ pub struct ExecutorSignature {
19
+ /// Admin's Ed25519 public key (32 bytes) - must correspond to a registered admin
20
+ pub public_key: BytesN<32>,
21
+ /// Ed25519 signature (64 bytes) over the signature_payload
22
+ pub signature: BytesN<64>,
23
+ }
24
+
25
+ // ============================================================================
26
+ // Custom Account Interface Implementation
27
+ // ============================================================================
28
+
29
+ #[contractimpl]
30
+ impl CustomAccountInterface for LzExecutor {
31
+ type Signature = ExecutorSignature;
32
+ type Error = ExecutorError;
33
+
34
+ /// Verifies authorization for the executor contract.
35
+ ///
36
+ /// The public key must correspond to a registered admin and must have signed the signature_payload.
37
+ /// Uses Ed25519 signature verification.
38
+ /// Only whitelisted function calls are authorized.
39
+ fn __check_auth(
40
+ env: Env,
41
+ signature_payload: Hash<32>,
42
+ auth_data: Self::Signature,
43
+ auth_contexts: Vec<Context>,
44
+ ) -> Result<(), Self::Error> {
45
+ Self::verify_admin_signature(&env, &signature_payload, &auth_data)?;
46
+ Self::validate_auth_contexts(&env, &auth_contexts)?;
47
+ Ok(())
48
+ }
49
+ }
50
+
51
+ // ============================================================================
52
+ // Internal Helper Functions
53
+ // ============================================================================
54
+
55
+ impl LzExecutor {
56
+ /// Verifies that the signature is from a registered admin.
57
+ ///
58
+ /// Converts the public key to an address, checks admin registration,
59
+ /// and verifies the Ed25519 signature over the payload.
60
+ fn verify_admin_signature(
61
+ env: &Env,
62
+ signature_payload: &Hash<32>,
63
+ auth_data: &ExecutorSignature,
64
+ ) -> Result<(), ExecutorError> {
65
+ let admin = Address::from_payload(env, AddressPayload::AccountIdPublicKeyEd25519(auth_data.public_key.clone()));
66
+ if !Self::is_admin(env, &admin) {
67
+ return Err(ExecutorError::Unauthorized);
68
+ }
69
+ env.crypto().ed25519_verify(&auth_data.public_key, &signature_payload.clone().into(), &auth_data.signature);
70
+ Ok(())
71
+ }
72
+
73
+ /// Validates that the first auth context is a whitelisted (contract, function) pair.
74
+ /// Sub-invocations are trusted since they're controlled by the whitelisted contract.
75
+ fn validate_auth_contexts(env: &Env, contexts: &Vec<Context>) -> Result<(), ExecutorError> {
76
+ let first_context = contexts.first().ok_or(ExecutorError::UnauthorizedContext)?;
77
+
78
+ match first_context {
79
+ Context::Contract(contract_context) => {
80
+ // Check if (contract, fn_name) pair is whitelisted
81
+ if !Self::is_whitelisted_fn(env, &contract_context.contract, &contract_context.fn_name) {
82
+ return Err(ExecutorError::UnauthorizedContext);
83
+ }
84
+ }
85
+ // Contract creation is not allowed
86
+ Context::CreateContractHostFn(_) | Context::CreateContractWithCtorHostFn(_) => {
87
+ return Err(ExecutorError::UnauthorizedContext);
88
+ }
89
+ }
90
+
91
+ Ok(())
92
+ }
93
+ }