@layerzerolabs/protocol-stellar-v2 0.2.19 → 0.2.20

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 (125) hide show
  1. package/.turbo/turbo-build.log +245 -222
  2. package/.turbo/turbo-lint.log +77 -70
  3. package/.turbo/turbo-test.log +1385 -1221
  4. package/Cargo.lock +13 -3
  5. package/Cargo.toml +2 -0
  6. package/contracts/ERROR_SPEC.md +8 -1
  7. package/contracts/common-macros/src/contract_ttl.rs +18 -7
  8. package/contracts/common-macros/src/lib.rs +4 -4
  9. package/contracts/common-macros/src/tests/contract_ttl.rs +1 -1
  10. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +2 -1
  11. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +7 -12
  12. package/contracts/common-macros/src/upgradeable.rs +15 -21
  13. package/contracts/message-libs/uln-302/src/events.rs +4 -0
  14. package/contracts/message-libs/uln-302/src/send_uln.rs +22 -6
  15. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +38 -64
  16. package/contracts/oapps/counter/Cargo.toml +1 -0
  17. package/contracts/oapps/counter/integration_tests/setup_uln.rs +1 -1
  18. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +113 -65
  19. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +111 -82
  20. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +293 -65
  21. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +331 -56
  22. package/contracts/oapps/oft/src/extensions/oft_fee.rs +18 -2
  23. package/contracts/oapps/oft/src/extensions/pausable.rs +19 -4
  24. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +52 -28
  25. package/contracts/oapps/oft/src/oft.rs +29 -41
  26. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +3 -25
  27. package/contracts/oapps/oft-core/integration-tests/setup.rs +2 -2
  28. package/contracts/oapps/oft-core/src/oft_core.rs +247 -207
  29. package/contracts/oapps/oft-core/src/tests/test_utils.rs +4 -4
  30. package/contracts/upgrader/src/lib.rs +30 -57
  31. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
  32. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
  33. package/contracts/upgrader/src/tests/test_upgrader.rs +44 -35
  34. package/contracts/utils/src/buffer_reader.rs +1 -0
  35. package/contracts/utils/src/errors.rs +3 -1
  36. package/contracts/utils/src/tests/upgradeable.rs +372 -175
  37. package/contracts/utils/src/ttl_configurable.rs +3 -3
  38. package/contracts/utils/src/upgradeable.rs +48 -23
  39. package/contracts/workers/dvn/Cargo.toml +1 -0
  40. package/contracts/workers/dvn/src/auth.rs +12 -42
  41. package/contracts/workers/dvn/src/dvn.rs +16 -31
  42. package/contracts/workers/dvn/src/errors.rs +0 -1
  43. package/contracts/workers/dvn/src/interfaces/dvn.rs +35 -0
  44. package/contracts/workers/dvn/src/lib.rs +4 -3
  45. package/contracts/workers/dvn/src/tests/auth.rs +1 -1
  46. package/contracts/workers/dvn/src/tests/dvn.rs +19 -15
  47. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +2 -4
  48. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +1 -3
  49. package/contracts/workers/dvn/src/tests/setup.rs +5 -9
  50. package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
  51. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -5
  52. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +2 -3
  53. package/contracts/workers/executor/Cargo.toml +1 -0
  54. package/contracts/workers/executor/src/executor.rs +15 -26
  55. package/contracts/workers/executor-fee-lib/Cargo.toml +2 -1
  56. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +63 -5
  57. package/contracts/workers/executor-fee-lib/src/executor_option.rs +28 -1
  58. package/contracts/workers/executor-fee-lib/src/lib.rs +3 -0
  59. package/contracts/workers/executor-fee-lib/src/tests/executor_fee_lib.rs +701 -0
  60. package/contracts/workers/executor-fee-lib/src/tests/executor_option.rs +370 -0
  61. package/contracts/workers/executor-fee-lib/src/tests/mod.rs +4 -0
  62. package/contracts/workers/executor-fee-lib/src/tests/setup.rs +60 -0
  63. package/contracts/workers/executor-helper/src/lib.rs +3 -0
  64. package/contracts/workers/executor-helper/src/tests/executor_helper.rs +184 -0
  65. package/contracts/workers/executor-helper/src/tests/mod.rs +2 -0
  66. package/contracts/workers/executor-helper/src/tests/setup.rs +366 -0
  67. package/contracts/workers/fee-lib-interfaces/Cargo.toml +14 -0
  68. package/contracts/workers/{worker/src/interfaces/mod.rs → fee-lib-interfaces/src/lib.rs} +4 -3
  69. package/contracts/workers/price-feed/Cargo.toml +2 -1
  70. package/contracts/workers/price-feed/src/events.rs +1 -1
  71. package/contracts/workers/price-feed/src/lib.rs +3 -0
  72. package/contracts/workers/price-feed/src/price_feed.rs +6 -12
  73. package/contracts/workers/price-feed/src/storage.rs +1 -1
  74. package/contracts/workers/price-feed/src/tests/mod.rs +2 -0
  75. package/contracts/workers/price-feed/src/tests/price_feed.rs +869 -0
  76. package/contracts/workers/price-feed/src/tests/setup.rs +70 -0
  77. package/contracts/workers/price-feed/src/types.rs +1 -1
  78. package/contracts/workers/worker/src/errors.rs +0 -3
  79. package/contracts/workers/worker/src/lib.rs +0 -2
  80. package/contracts/workers/worker/src/storage.rs +32 -29
  81. package/contracts/workers/worker/src/tests/setup.rs +1 -7
  82. package/contracts/workers/worker/src/tests/worker.rs +50 -42
  83. package/contracts/workers/worker/src/worker.rs +49 -58
  84. package/package.json +3 -3
  85. package/sdk/.turbo/turbo-test.log +220 -218
  86. package/sdk/dist/generated/bml.d.ts +12 -4
  87. package/sdk/dist/generated/bml.js +8 -6
  88. package/sdk/dist/generated/counter.d.ts +12 -4
  89. package/sdk/dist/generated/counter.js +8 -6
  90. package/sdk/dist/generated/dvn.d.ts +404 -365
  91. package/sdk/dist/generated/dvn.js +55 -53
  92. package/sdk/dist/generated/dvn_fee_lib.d.ts +224 -268
  93. package/sdk/dist/generated/dvn_fee_lib.js +22 -53
  94. package/sdk/dist/generated/endpoint.d.ts +12 -4
  95. package/sdk/dist/generated/endpoint.js +8 -6
  96. package/sdk/dist/generated/executor.d.ts +370 -326
  97. package/sdk/dist/generated/executor.js +47 -44
  98. package/sdk/dist/generated/executor_fee_lib.d.ts +258 -302
  99. package/sdk/dist/generated/executor_fee_lib.js +21 -52
  100. package/sdk/dist/generated/executor_helper.d.ts +26 -190
  101. package/sdk/dist/generated/executor_helper.js +22 -27
  102. package/sdk/dist/generated/layerzero_view.d.ts +1271 -0
  103. package/sdk/dist/generated/layerzero_view.js +294 -0
  104. package/sdk/dist/generated/oft.d.ts +49 -40
  105. package/sdk/dist/generated/oft.js +25 -23
  106. package/sdk/dist/generated/price_feed.d.ts +225 -269
  107. package/sdk/dist/generated/price_feed.js +22 -53
  108. package/sdk/dist/generated/sml.d.ts +12 -4
  109. package/sdk/dist/generated/sml.js +8 -6
  110. package/sdk/dist/generated/treasury.d.ts +12 -4
  111. package/sdk/dist/generated/treasury.js +8 -6
  112. package/sdk/dist/generated/uln302.d.ts +12 -4
  113. package/sdk/dist/generated/uln302.js +10 -8
  114. package/sdk/dist/generated/upgrader.d.ts +189 -18
  115. package/sdk/dist/generated/upgrader.js +84 -4
  116. package/sdk/dist/index.d.ts +1 -0
  117. package/sdk/dist/index.js +2 -0
  118. package/sdk/package.json +1 -1
  119. package/sdk/src/index.ts +3 -0
  120. package/sdk/test/oft-sml.test.ts +4 -4
  121. package/sdk/test/upgrader.test.ts +2 -3
  122. package/tools/ts-bindings-gen/src/main.rs +2 -1
  123. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/dvn_fee_lib.rs +0 -0
  124. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/executor_fee_lib.rs +0 -0
  125. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/price_feed.rs +0 -0
package/Cargo.lock CHANGED
@@ -339,6 +339,7 @@ dependencies = [
339
339
  "executor",
340
340
  "executor-fee-lib",
341
341
  "executor-helper",
342
+ "fee-lib-interfaces",
342
343
  "k256",
343
344
  "message-lib-common",
344
345
  "oapp",
@@ -607,6 +608,7 @@ dependencies = [
607
608
  "common-macros",
608
609
  "ed25519-dalek",
609
610
  "endpoint-v2",
611
+ "fee-lib-interfaces",
610
612
  "insta",
611
613
  "k256",
612
614
  "message-lib-common",
@@ -622,10 +624,10 @@ name = "dvn-fee-lib"
622
624
  version = "0.0.1"
623
625
  dependencies = [
624
626
  "common-macros",
627
+ "fee-lib-interfaces",
625
628
  "message-lib-common",
626
629
  "soroban-sdk",
627
630
  "utils",
628
- "worker",
629
631
  ]
630
632
 
631
633
  [[package]]
@@ -740,6 +742,7 @@ dependencies = [
740
742
  "cfg-if",
741
743
  "common-macros",
742
744
  "endpoint-v2",
745
+ "fee-lib-interfaces",
743
746
  "message-lib-common",
744
747
  "soroban-sdk",
745
748
  "utils",
@@ -751,10 +754,10 @@ name = "executor-fee-lib"
751
754
  version = "0.0.1"
752
755
  dependencies = [
753
756
  "common-macros",
757
+ "fee-lib-interfaces",
754
758
  "message-lib-common",
755
759
  "soroban-sdk",
756
760
  "utils",
757
- "worker",
758
761
  ]
759
762
 
760
763
  [[package]]
@@ -769,6 +772,13 @@ dependencies = [
769
772
  "worker",
770
773
  ]
771
774
 
775
+ [[package]]
776
+ name = "fee-lib-interfaces"
777
+ version = "0.0.1"
778
+ dependencies = [
779
+ "soroban-sdk",
780
+ ]
781
+
772
782
  [[package]]
773
783
  name = "ff"
774
784
  version = "0.13.1"
@@ -1298,9 +1308,9 @@ name = "price-feed"
1298
1308
  version = "0.0.1"
1299
1309
  dependencies = [
1300
1310
  "common-macros",
1311
+ "fee-lib-interfaces",
1301
1312
  "soroban-sdk",
1302
1313
  "utils",
1303
- "worker",
1304
1314
  ]
1305
1315
 
1306
1316
  [[package]]
package/Cargo.toml CHANGED
@@ -26,6 +26,7 @@ uln302 = { path = "contracts/message-libs/uln-302", default-features = false }
26
26
  oapp = { path = "contracts/oapps/oapp" }
27
27
  simple-message-lib = { path = "contracts/message-libs/simple-message-lib" }
28
28
  treasury = { path = "contracts/message-libs/treasury" }
29
+ fee-lib-interfaces = { path = "contracts/workers/fee-lib-interfaces" }
29
30
  worker = { path = "contracts/workers/worker" }
30
31
  executor = { path = "contracts/workers/executor" }
31
32
  executor-helper = { path = "contracts/workers/executor-helper" }
@@ -34,6 +35,7 @@ dvn = { path = "contracts/workers/dvn" }
34
35
  dvn-fee-lib = { path = "contracts/workers/dvn-fee-lib" }
35
36
  price-feed = { path = "contracts/workers/price-feed" }
36
37
  oft-core = { path = "contracts/oapps/oft-core" }
38
+ oft = { path = "contracts/oapps/oft" }
37
39
  stellar-macros = { git = "https://github.com/OpenZeppelin/stellar-contracts.git", tag = "v0.5.1" }
38
40
  stellar-tokens = { git = "https://github.com/OpenZeppelin/stellar-contracts.git", tag = "v0.5.1" }
39
41
  stellar-contract-utils = { git = "https://github.com/OpenZeppelin/stellar-contracts.git", tag = "v0.5.1" }
@@ -23,6 +23,12 @@ Each library has a unique error code range to:
23
23
  - UpgradeableError: 1050-1059
24
24
  - MultisigError: 1060-1069
25
25
 
26
+ Example from `oft/extensions` (3100-3199):
27
+
28
+ - OFTFeeError: 3100-3109
29
+ - OFTPausableError: 3110-3119
30
+ - RateLimitError: 3120-3129
31
+
26
32
  If an error type exceeds 10 errors (e.g., 12 errors), it extends into the next block but the following error type should start at the next 10-unit boundary (e.g., if errors are 1000-1011, next sub-range starts at 1020).
27
33
 
28
34
  - **Auto-increment**: Within each error enum, values auto-increment from the starting value.
@@ -39,6 +45,7 @@ Each library has a unique error code range to:
39
45
  | 2000 - 2099 | OApp Lib | oapp | `oapps/oapp/src/errors.rs` |
40
46
  | 2100 - 2999 | OApp Lib | (reserved) | Future OApp libs |
41
47
  | 3000 - 3099 | OFT Lib | oft-core | `oapps/oft-core/src/errors.rs` |
42
- | 3100 - 3999 | OFT Lib | (reserved) | Future OFT libs |
48
+ | 3100 - 3199 | OFT Lib | oft (extensions) | `oapps/oft/src/extensions/` |
49
+ | 3200 - 3999 | OFT Lib | (reserved) | Future OFT libs |
43
50
 
44
51
  ---
@@ -4,6 +4,9 @@ use quote::quote;
4
4
  use syn::{ImplItem, ItemImpl, ItemTrait, TraitItem, Visibility};
5
5
 
6
6
  /// Generates a `#[soroban_sdk::contractimpl]` with automatic instance TTL extension.
7
+ ///
8
+ /// - For `__constructor` methods: injects `ttl_configurable::init_default_ttl_configs(env)`
9
+ /// - For other methods: injects TTL extension logic to extend instance TTL if configured
7
10
  pub fn contractimpl_with_ttl(attr: TokenStream, input: TokenStream) -> TokenStream {
8
11
  let mut impl_block: ItemImpl = syn::parse2(input).unwrap_or_else(|e| panic!("failed to parse impl block: {}", e));
9
12
 
@@ -17,16 +20,16 @@ pub fn contractimpl_with_ttl(attr: TokenStream, input: TokenStream) -> TokenStre
17
20
  continue;
18
21
  }
19
22
 
20
- // Skip the constructor as TTL config is typically not set during initialization
21
- if method.sig.ident == "__constructor" {
22
- continue;
23
- }
24
-
25
23
  // Skip methods without Env parameter
26
24
  let Some(env_param) = utils::find_env_param(&method.sig.inputs) else { continue };
27
25
 
28
- // Inject TTL extension at the start of the method body
29
- method.block.stmts.insert(0, extend_instance_ttl_stmt(&env_param));
26
+ if method.sig.ident == "__constructor" {
27
+ // Inject default TTL config initialization in constructor
28
+ method.block.stmts.insert(0, init_default_ttl_configs_stmt(&env_param));
29
+ } else {
30
+ // Inject TTL extension at the start of other methods
31
+ method.block.stmts.insert(0, extend_instance_ttl_stmt(&env_param));
32
+ }
30
33
  }
31
34
 
32
35
  let contract_attr = if attr.is_empty() {
@@ -72,6 +75,14 @@ pub fn contracttrait_with_ttl(attr: TokenStream, input: TokenStream) -> TokenStr
72
75
  }
73
76
  }
74
77
 
78
+ /// Generates a statement that initializes default TTL configs in the constructor.
79
+ fn init_default_ttl_configs_stmt(env_param: &utils::EnvParam<'_>) -> syn::Stmt {
80
+ let env_ident = env_param.ident;
81
+ syn::parse_quote! {
82
+ utils::ttl_configurable::init_default_ttl_configs(#env_ident);
83
+ }
84
+ }
85
+
75
86
  /// Generates a statement that extends instance TTL if configured.
76
87
  fn extend_instance_ttl_stmt(env_param: &utils::EnvParam<'_>) -> syn::Stmt {
77
88
  let env_ref = env_param.as_ref_tokens();
@@ -386,9 +386,9 @@ pub fn contract_trait(attr: TokenStream, item: TokenStream) -> TokenStream {
386
386
  // Upgradeable Macro
387
387
  // ============================================================================
388
388
 
389
- /// Generates upgradeable implementation with auth-based access control.
389
+ /// Generates upgradeable implementation using the `Upgradeable` trait's default methods.
390
390
  ///
391
- /// Implements the `Upgradeable` trait for contract upgrade and migration functionality.
391
+ /// This macro implements `Upgradeable` using the trait's default methods (which include auth).
392
392
  ///
393
393
  /// # Requirements
394
394
  /// - The contract must implement the `Auth` trait (via `#[ownable]` or `Multisig`)
@@ -403,7 +403,7 @@ pub fn contract_trait(attr: TokenStream, item: TokenStream) -> TokenStream {
403
403
  /// impl utils::upgradeable::UpgradeableInternal for MyContract {
404
404
  /// type MigrationData = ();
405
405
  ///
406
- /// fn _migrate(env: &Env, migration_data: &Self::MigrationData) {
406
+ /// fn __migrate(env: &Env, migration_data: &Self::MigrationData) {
407
407
  /// // Migration logic here
408
408
  /// }
409
409
  /// }
@@ -411,7 +411,7 @@ pub fn contract_trait(attr: TokenStream, item: TokenStream) -> TokenStream {
411
411
  ///
412
412
  /// Generated code includes:
413
413
  /// - `upgrade(env, new_wasm_hash)` - Upgrades the contract WASM (auth required)
414
- /// - `migrate(env, migration_data)` - Runs migration after upgrade (auth required)
414
+ /// - `migrate(env, migration_data)` - Runs migration after upgrade (auth required, XDR-decodes `Bytes` to `MigrationData`)
415
415
  /// - `contractmeta!` with `binver` set to the Cargo package version (if not 0.0.0)
416
416
  #[proc_macro_attribute]
417
417
  pub fn upgradeable(_attr: TokenStream, item: TokenStream) -> TokenStream {
@@ -49,7 +49,7 @@ fn snapshot_generated_contractimpl_code() {
49
49
  value * 7
50
50
  }
51
51
 
52
- /// Constructor method - should NOT have TTL extension
52
+ /// Constructor method - should have init_default_ttl_configs
53
53
  pub fn __constructor(env: &Env, value: u32) {
54
54
  let _ = value * 2;
55
55
  }
@@ -52,8 +52,9 @@ impl MyContract {
52
52
  pub(crate) fn pub_crate_with_env(env: Env, value: u32) -> u32 {
53
53
  value * 7
54
54
  }
55
- /// Constructor method - should NOT have TTL extension
55
+ /// Constructor method - should have init_default_ttl_configs
56
56
  pub fn __constructor(env: &Env, value: u32) {
57
+ utils::ttl_configurable::init_default_ttl_configs(env);
57
58
  let _ = value * 2;
58
59
  }
59
60
  }
@@ -6,16 +6,11 @@ expression: formatted
6
6
  pub struct MyContract;
7
7
  use utils::upgradeable::Upgradeable as _;
8
8
  soroban_sdk::contractmeta!(key = "binver", val = "0.0.1");
9
- type MigrationData = <MyContract as utils::upgradeable::UpgradeableInternal>::MigrationData;
10
- /// Implement the Upgradeable trait for the contract.
11
- #[common_macros::contract_impl]
12
- impl utils::upgradeable::Upgradeable for MyContract {
13
- #[common_macros::only_auth]
14
- fn upgrade(env: &soroban_sdk::Env, new_wasm_hash: soroban_sdk::BytesN<32>) {
15
- utils::upgradeable::upgrade(env, new_wasm_hash)
16
- }
17
- #[common_macros::only_auth]
18
- fn migrate(env: &soroban_sdk::Env, migration_data: &MigrationData) {
19
- utils::upgradeable::migrate::<Self>(env, migration_data)
20
- }
9
+ #[doc(hidden)]
10
+ mod __upgradeable_impl_my_contract {
11
+ use super::*;
12
+ use soroban_sdk::{Bytes, BytesN};
13
+ use utils::upgradeable::{Upgradeable, UpgradeableInternal};
14
+ #[common_macros::contract_impl(contracttrait)]
15
+ impl Upgradeable for MyContract {}
21
16
  }
@@ -1,3 +1,6 @@
1
+ //! Upgradeable macro for Stellar smart contracts.
2
+
3
+ use crate::utils;
1
4
  use proc_macro2::TokenStream;
2
5
  use quote::quote;
3
6
  use syn::ItemStruct;
@@ -10,7 +13,7 @@ use syn::ItemStruct;
10
13
  ///
11
14
  /// # Behavior
12
15
  ///
13
- /// - Implements the `upgrade` and `migrate` functions with auth-based access control.
16
+ /// - Implements the `Upgradeable` trait using its default methods (which include auth).
14
17
  /// - Sets the contract crate version as `"binver"` metadata using
15
18
  /// `soroban_sdk::contractmeta!`. Gets the crate version via the env variable
16
19
  /// `CARGO_PKG_VERSION` which corresponds to the "version" attribute in
@@ -26,35 +29,26 @@ use syn::ItemStruct;
26
29
  pub fn generate_upgradeable_impl(input: TokenStream) -> TokenStream {
27
30
  let item_struct: ItemStruct = syn::parse2(input).unwrap_or_else(|e| panic!("failed to parse struct: {}", e));
28
31
  let name = &item_struct.ident;
32
+ let impl_mod = utils::impl_mod_ident(name, "upgradeable");
29
33
 
30
34
  let binver = set_binver_from_env();
31
35
 
32
- let upgradeable_impl = quote! {
36
+ quote! {
37
+ #item_struct
38
+
33
39
  use utils::upgradeable::Upgradeable as _;
34
40
 
35
41
  #binver
36
42
 
37
- // Type alias to avoid path complexity in contractimpl
38
- type MigrationData = <#name as utils::upgradeable::UpgradeableInternal>::MigrationData;
43
+ #[doc(hidden)]
44
+ mod #impl_mod {
45
+ use super::*;
46
+ use soroban_sdk::{Bytes, BytesN};
47
+ use utils::upgradeable::{Upgradeable, UpgradeableInternal};
39
48
 
40
- /// Implement the Upgradeable trait for the contract.
41
- #[common_macros::contract_impl]
42
- impl utils::upgradeable::Upgradeable for #name {
43
- #[common_macros::only_auth]
44
- fn upgrade(env: &soroban_sdk::Env, new_wasm_hash: soroban_sdk::BytesN<32>) {
45
- utils::upgradeable::upgrade(env, new_wasm_hash)
46
- }
47
-
48
- #[common_macros::only_auth]
49
- fn migrate(env: &soroban_sdk::Env, migration_data: &MigrationData) {
50
- utils::upgradeable::migrate::<Self>(env, migration_data)
51
- }
49
+ #[common_macros::contract_impl(contracttrait)]
50
+ impl Upgradeable for #name {}
52
51
  }
53
- };
54
-
55
- quote! {
56
- #item_struct
57
- #upgradeable_impl
58
52
  }
59
53
  }
60
54
 
@@ -58,12 +58,16 @@ pub struct DefaultReceiveUlnConfigsSet {
58
58
  pub struct ExecutorFeePaid {
59
59
  #[topic]
60
60
  pub executor: Address,
61
+ #[topic]
62
+ pub guid: BytesN<32>,
61
63
  pub fee: FeeRecipient,
62
64
  }
63
65
 
64
66
  #[contractevent]
65
67
  #[derive(Clone, Debug, Eq, PartialEq)]
66
68
  pub struct DVNFeePaid {
69
+ #[topic]
70
+ pub guid: BytesN<32>,
67
71
  pub dvns: Vec<Address>,
68
72
  pub fees: Vec<FeeRecipient>,
69
73
  }
@@ -63,12 +63,25 @@ impl ISendLib for Uln302 {
63
63
  prepare_packet_and_options(env, packet, options);
64
64
 
65
65
  // Executor fee
66
- let executor_fee_recipient =
67
- Self::assign_executor(env, &packet.sender, packet.dst_eid, packet.message.len(), &executor_options);
66
+ let executor_fee_recipient = Self::assign_executor(
67
+ env,
68
+ &packet.guid,
69
+ &packet.sender,
70
+ packet.dst_eid,
71
+ packet.message.len(),
72
+ &executor_options,
73
+ );
68
74
 
69
75
  // DVNs fees
70
- let dvns_fee_recipients =
71
- Self::assign_dvns(env, &packet.sender, packet.dst_eid, &packet_header, &payload_hash, &dvn_options);
76
+ let dvns_fee_recipients = Self::assign_dvns(
77
+ env,
78
+ &packet.guid,
79
+ &packet.sender,
80
+ packet.dst_eid,
81
+ &packet_header,
82
+ &payload_hash,
83
+ &dvn_options,
84
+ );
72
85
 
73
86
  // Collect all worker fees
74
87
  let mut native_fee_recipients = vec![env, executor_fee_recipient];
@@ -257,6 +270,7 @@ impl Uln302 {
257
270
  /// Assigns an executor job and returns the fee recipient.
258
271
  fn assign_executor(
259
272
  env: &Env,
273
+ guid: &BytesN<32>,
260
274
  sender: &Address,
261
275
  dst_eid: u32,
262
276
  message_length: u32,
@@ -270,13 +284,15 @@ impl Uln302 {
270
284
  let recipient =
271
285
  executor_client.assign_job(&env.current_contract_address(), sender, &dst_eid, &message_length, options);
272
286
 
273
- ExecutorFeePaid { executor: executor_client.address.clone(), fee: recipient.clone() }.publish(env);
287
+ ExecutorFeePaid { guid: guid.clone(), executor: executor_client.address.clone(), fee: recipient.clone() }
288
+ .publish(env);
274
289
  recipient
275
290
  }
276
291
 
277
292
  /// Assigns DVN jobs and returns fee recipients for all DVNs.
278
293
  fn assign_dvns(
279
294
  env: &Env,
295
+ guid: &BytesN<32>,
280
296
  sender: &Address,
281
297
  dst_eid: u32,
282
298
  packet_header: &Bytes,
@@ -305,7 +321,7 @@ impl Uln302 {
305
321
  dvns.push_back(dvn_addr);
306
322
  }
307
323
 
308
- DVNFeePaid { dvns, fees: fees.clone() }.publish(env);
324
+ DVNFeePaid { guid: guid.clone(), dvns, fees: fees.clone() }.publish(env);
309
325
  fees
310
326
  }
311
327
  }
@@ -76,10 +76,18 @@ fn test_send_events_emittance() {
76
76
  &setup.env,
77
77
  &setup.uln302.address,
78
78
  &[
79
- ExecutorFeePaid { executor: executor.clone(), fee: native_fee_recipients.get(0).unwrap().clone() }
80
- .expected(&setup.env),
81
- DVNFeePaid { dvns: dvns.slice(0..2).clone(), fees: native_fee_recipients.slice(1..3).clone() }
82
- .expected(&setup.env),
79
+ ExecutorFeePaid {
80
+ executor: executor.clone(),
81
+ guid: packet.guid.clone(),
82
+ fee: native_fee_recipients.get(0).unwrap().clone(),
83
+ }
84
+ .expected(&setup.env),
85
+ DVNFeePaid {
86
+ guid: packet.guid.clone(),
87
+ dvns: dvns.slice(0..2).clone(),
88
+ fees: native_fee_recipients.slice(1..3).clone(),
89
+ }
90
+ .expected(&setup.env),
83
91
  ],
84
92
  );
85
93
 
@@ -92,17 +100,11 @@ fn test_send_events_emittance() {
92
100
  );
93
101
  assert_eq!(
94
102
  native_fee_recipients.get(1).unwrap(),
95
- FeeRecipient {
96
- amount: DVN_FEE[0],
97
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
98
- }
103
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
99
104
  );
100
105
  assert_eq!(
101
106
  native_fee_recipients.get(2).unwrap(),
102
- FeeRecipient {
103
- amount: DVN_FEE[1],
104
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient()
105
- }
107
+ FeeRecipient { amount: DVN_FEE[1], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient() }
106
108
  );
107
109
  assert_eq!(
108
110
  native_fee_recipients.get(3).unwrap(),
@@ -172,10 +174,18 @@ fn test_send_events_emittance_with_zro() {
172
174
  &setup.env,
173
175
  &setup.uln302.address,
174
176
  &[
175
- ExecutorFeePaid { executor: executor.clone(), fee: native_fee_recipients.get(0).unwrap().clone() }
176
- .expected(&setup.env),
177
- DVNFeePaid { dvns: dvns.slice(0..2).clone(), fees: native_fee_recipients.slice(1..3).clone() }
178
- .expected(&setup.env),
177
+ ExecutorFeePaid {
178
+ executor: executor.clone(),
179
+ guid: packet.guid.clone(),
180
+ fee: native_fee_recipients.get(0).unwrap().clone(),
181
+ }
182
+ .expected(&setup.env),
183
+ DVNFeePaid {
184
+ guid: packet.guid.clone(),
185
+ dvns: dvns.slice(0..2).clone(),
186
+ fees: native_fee_recipients.slice(1..3).clone(),
187
+ }
188
+ .expected(&setup.env),
179
189
  ],
180
190
  );
181
191
 
@@ -188,17 +198,11 @@ fn test_send_events_emittance_with_zro() {
188
198
  );
189
199
  assert_eq!(
190
200
  native_fee_recipients.get(1).unwrap(),
191
- FeeRecipient {
192
- amount: DVN_FEE[0],
193
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
194
- }
201
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
195
202
  );
196
203
  assert_eq!(
197
204
  native_fee_recipients.get(2).unwrap(),
198
- FeeRecipient {
199
- amount: DVN_FEE[1],
200
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient()
201
- }
205
+ FeeRecipient { amount: DVN_FEE[1], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient() }
202
206
  );
203
207
  assert_eq!(
204
208
  zro_fee_recipients.get(0).unwrap(),
@@ -264,10 +268,7 @@ fn test_send_single_dvn() {
264
268
  );
265
269
  assert_eq!(
266
270
  native_fee_recipients.get(1).unwrap(),
267
- FeeRecipient {
268
- amount: DVN_FEE[0],
269
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
270
- }
271
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
271
272
  );
272
273
  assert_eq!(
273
274
  native_fee_recipients.get(2).unwrap(),
@@ -378,17 +379,11 @@ fn test_send_multiple_dvns() {
378
379
  );
379
380
  assert_eq!(
380
381
  native_fee_recipients.get(1).unwrap(),
381
- FeeRecipient {
382
- amount: DVN_FEE[0],
383
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
384
- }
382
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
385
383
  );
386
384
  assert_eq!(
387
385
  native_fee_recipients.get(2).unwrap(),
388
- FeeRecipient {
389
- amount: DVN_FEE[1],
390
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient()
391
- }
386
+ FeeRecipient { amount: DVN_FEE[1], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient() }
392
387
  );
393
388
  assert_eq!(
394
389
  native_fee_recipients.get(3).unwrap(),
@@ -454,10 +449,7 @@ fn test_send_with_only_optional_dvns() {
454
449
  );
455
450
  assert_eq!(
456
451
  native_fee_recipients.get(1).unwrap(),
457
- FeeRecipient {
458
- amount: DVN_FEE[0],
459
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
460
- }
452
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
461
453
  );
462
454
  assert_eq!(
463
455
  native_fee_recipients.get(2).unwrap(),
@@ -628,17 +620,11 @@ fn test_send_with_missing_dvn_options() {
628
620
  );
629
621
  assert_eq!(
630
622
  native_fee_recipients.get(1).unwrap(),
631
- FeeRecipient {
632
- amount: DVN_FEE[0],
633
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
634
- }
623
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
635
624
  );
636
625
  assert_eq!(
637
626
  native_fee_recipients.get(2).unwrap(),
638
- FeeRecipient {
639
- amount: DVN_FEE[1],
640
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient()
641
- }
627
+ FeeRecipient { amount: DVN_FEE[1], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient() }
642
628
  );
643
629
  assert_eq!(
644
630
  native_fee_recipients.get(3).unwrap(),
@@ -703,10 +689,7 @@ fn test_send_with_missing_executor_options() {
703
689
  );
704
690
  assert_eq!(
705
691
  native_fee_recipients.get(1).unwrap(),
706
- FeeRecipient {
707
- amount: DVN_FEE[0],
708
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
709
- }
692
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
710
693
  );
711
694
  assert_eq!(
712
695
  native_fee_recipients.get(2).unwrap(),
@@ -804,26 +787,17 @@ fn test_send_derives_from_quote() {
804
787
  // DVN 0 (first required)
805
788
  assert_eq!(
806
789
  native_fee_recipients.get(1).unwrap(),
807
- FeeRecipient {
808
- amount: DVN_FEE[0],
809
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient()
810
- }
790
+ FeeRecipient { amount: DVN_FEE[0], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(0)).recipient() }
811
791
  );
812
792
  // DVN 1 (second required)
813
793
  assert_eq!(
814
794
  native_fee_recipients.get(2).unwrap(),
815
- FeeRecipient {
816
- amount: DVN_FEE[1],
817
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient()
818
- }
795
+ FeeRecipient { amount: DVN_FEE[1], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(1)).recipient() }
819
796
  );
820
797
  // DVN 2 (optional)
821
798
  assert_eq!(
822
799
  native_fee_recipients.get(3).unwrap(),
823
- FeeRecipient {
824
- amount: DVN_FEE[2],
825
- to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(2)).recipient()
826
- }
800
+ FeeRecipient { amount: DVN_FEE[2], to: DummyDVNClient::new(&setup.env, &dvns.get_unchecked(2)).recipient() }
827
801
  );
828
802
 
829
803
  // Treasury fee is last
@@ -30,6 +30,7 @@ executor-fee-lib = { workspace = true }
30
30
  worker = { workspace = true }
31
31
  treasury = { workspace = true, features = ["testutils"] }
32
32
  price-feed = { workspace = true }
33
+ fee-lib-interfaces = { workspace = true }
33
34
  executor-helper = { workspace = true }
34
35
  # For real DVN signature verification in integration tests
35
36
  k256 = "0.13"
@@ -13,6 +13,7 @@ use endpoint_v2::{EndpointV2, EndpointV2Client};
13
13
  use executor::{DstConfig as ExecutorDstConfig, ExecutorClient, LzExecutor, SetDstConfigParam};
14
14
  use executor_fee_lib::ExecutorFeeLib;
15
15
  use executor_helper::{ExecutorHelper, ExecutorHelperClient};
16
+ use fee_lib_interfaces::Price;
16
17
  use price_feed::{types::UpdatePrice, LzPriceFeed};
17
18
  use soroban_sdk::{
18
19
  testutils::{Address as _, MockAuth, MockAuthInvoke},
@@ -25,7 +26,6 @@ use uln302::{
25
26
  Uln302, Uln302Client, UlnConfig,
26
27
  };
27
28
  use utils::{buffer_reader::BufferReader, buffer_writer::BufferWriter};
28
- use worker::Price;
29
29
 
30
30
  pub const CONFIRMATIONS: u64 = 1;
31
31
  pub const MAX_MESSAGE_SIZE: u32 = 10000;