@layerzerolabs/protocol-stellar-v2 0.2.40 → 0.2.43

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 +312 -397
  2. package/.turbo/turbo-lint.log +185 -245
  3. package/.turbo/turbo-test.log +1846 -1942
  4. package/Cargo.lock +22 -127
  5. package/Cargo.toml +4 -6
  6. package/contracts/common-macros/src/lib.rs +38 -15
  7. package/contracts/common-macros/src/lz_contract.rs +12 -21
  8. package/contracts/common-macros/src/tests/lz_contract.rs +17 -8
  9. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__lz_contract__snapshot_generated_lz_contract_code.snap +20 -0
  10. package/contracts/common-macros/src/upgradeable.rs +37 -30
  11. package/contracts/endpoint-v2/src/endpoint_v2.rs +4 -3
  12. package/contracts/endpoint-v2/src/errors.rs +2 -2
  13. package/contracts/endpoint-v2/src/messaging_channel.rs +11 -0
  14. package/contracts/endpoint-v2/src/messaging_composer.rs +1 -0
  15. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +12 -25
  16. package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +4 -4
  17. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +50 -10
  18. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +6 -35
  19. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +2 -2
  20. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +50 -1
  21. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +78 -0
  22. package/contracts/endpoint-v2/src/tests/messaging_channel/insert_and_drain_pending_nonces.rs +272 -0
  23. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +1 -0
  24. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +10 -5
  25. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +30 -0
  26. package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +25 -6
  27. package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +13 -11
  28. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +13 -10
  29. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +15 -11
  30. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +5 -3
  31. package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +1 -1
  32. package/contracts/macro-integration-tests/tests/runtime/ownable/two_step_transfer.rs +14 -12
  33. package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +3 -9
  34. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_invalid_inner_option.stderr +24 -1
  35. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +3 -3
  36. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/upgradeable_rbac.rs +44 -0
  37. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_auth_trait.rs +28 -0
  38. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_auth_trait.stderr +397 -0
  39. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +1 -0
  40. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +10 -10
  41. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +4 -0
  42. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +7 -0
  43. package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +5 -4
  44. package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +2 -0
  45. package/contracts/macro-integration-tests/tests/ui/ownable/pass/basic.rs +1 -1
  46. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/attr_args.stderr +1 -1
  47. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +2 -2
  48. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +2 -2
  49. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/rbac.rs +44 -0
  50. package/contracts/oapps/counter/integration_tests/utils.rs +5 -3
  51. package/contracts/oapps/counter/src/counter.rs +4 -3
  52. package/contracts/oapps/counter/src/tests/mod.rs +16 -1
  53. package/contracts/oapps/counter/src/tests/test_counter.rs +5 -2
  54. package/contracts/oapps/oapp/src/oapp_core.rs +22 -8
  55. package/contracts/oapps/oapp/src/oapp_options_type3.rs +7 -5
  56. package/contracts/oapps/oapp/src/tests/mod.rs +21 -0
  57. package/contracts/oapps/oapp/src/tests/oapp_core.rs +14 -11
  58. package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +17 -10
  59. package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +6 -3
  60. package/contracts/oapps/oapp/src/tests/oapp_sender.rs +5 -3
  61. package/contracts/oapps/oapp/src/tests/test_macros.rs +25 -0
  62. package/contracts/oapps/oapp-macros/src/generators.rs +12 -9
  63. package/contracts/oapps/oapp-macros/src/lib.rs +1 -1
  64. package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +15 -7
  65. package/contracts/oapps/oft/integration-tests/setup.rs +22 -4
  66. package/contracts/oapps/oft/integration-tests/utils.rs +94 -13
  67. package/contracts/oapps/oft/src/extensions/oft_fee.rs +23 -10
  68. package/contracts/oapps/oft/src/extensions/pausable.rs +31 -10
  69. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +9 -4
  70. package/contracts/oapps/oft/src/oft.rs +3 -3
  71. package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +39 -27
  72. package/contracts/oapps/oft/src/tests/extensions/pausable.rs +38 -24
  73. package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +87 -69
  74. package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +1 -0
  75. package/contracts/oapps/oft-core/integration-tests/setup.rs +28 -3
  76. package/contracts/oapps/oft-core/src/oft_core.rs +11 -6
  77. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +20 -20
  78. package/contracts/oapps/oft-core/src/tests/test_utils.rs +33 -3
  79. package/contracts/upgrader/src/lib.rs +67 -30
  80. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract3.wasm +0 -0
  81. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract4.wasm +0 -0
  82. package/contracts/upgrader/src/tests/test_upgrader.rs +50 -4
  83. package/contracts/utils/src/ownable.rs +16 -5
  84. package/contracts/utils/src/tests/ownable.rs +39 -39
  85. package/contracts/utils/src/upgradeable.rs +60 -17
  86. package/docs/oapp-guide.md +18 -13
  87. package/package.json +5 -5
  88. package/sdk/.turbo/turbo-test.log +359 -348
  89. package/sdk/dist/generated/bml.d.ts +4 -4
  90. package/sdk/dist/generated/bml.js +6 -6
  91. package/sdk/dist/generated/counter.d.ts +269 -123
  92. package/sdk/dist/generated/counter.js +45 -25
  93. package/sdk/dist/generated/dvn.d.ts +4 -6
  94. package/sdk/dist/generated/dvn.js +8 -8
  95. package/sdk/dist/generated/dvn_fee_lib.d.ts +8 -10
  96. package/sdk/dist/generated/dvn_fee_lib.js +8 -8
  97. package/sdk/dist/generated/endpoint.d.ts +9 -9
  98. package/sdk/dist/generated/endpoint.js +9 -9
  99. package/sdk/dist/generated/executor.d.ts +9 -11
  100. package/sdk/dist/generated/executor.js +11 -11
  101. package/sdk/dist/generated/executor_fee_lib.d.ts +9 -11
  102. package/sdk/dist/generated/executor_fee_lib.js +11 -11
  103. package/sdk/dist/generated/executor_helper.d.ts +4 -4
  104. package/sdk/dist/generated/executor_helper.js +6 -6
  105. package/sdk/dist/generated/layerzero_view.d.ts +9 -11
  106. package/sdk/dist/generated/layerzero_view.js +11 -11
  107. package/sdk/dist/generated/oft.d.ts +323 -156
  108. package/sdk/dist/generated/oft.js +65 -43
  109. package/sdk/dist/generated/price_feed.d.ts +8 -10
  110. package/sdk/dist/generated/price_feed.js +8 -8
  111. package/sdk/dist/generated/sac_manager.d.ts +8 -8
  112. package/sdk/dist/generated/sac_manager.js +6 -6
  113. package/sdk/dist/generated/sml.d.ts +9 -9
  114. package/sdk/dist/generated/sml.js +9 -9
  115. package/sdk/dist/generated/treasury.d.ts +9 -9
  116. package/sdk/dist/generated/treasury.js +9 -9
  117. package/sdk/dist/generated/uln302.d.ts +9 -9
  118. package/sdk/dist/generated/uln302.js +9 -9
  119. package/sdk/dist/generated/upgrader.d.ts +25 -16
  120. package/sdk/dist/generated/upgrader.js +5 -5
  121. package/sdk/package.json +1 -1
  122. package/sdk/test/counter-sml.test.ts +20 -0
  123. package/sdk/test/counter-uln.test.ts +20 -0
  124. package/sdk/test/oft-sml.test.ts +22 -0
  125. package/sdk/test/upgrader.test.ts +1 -0
  126. package/ts-bindings-gen.toml +67 -0
  127. package/turbo.json +1 -8
  128. package/tools/ts-bindings-gen/Cargo.toml +0 -16
  129. package/tools/ts-bindings-gen/src/main.rs +0 -214
@@ -0,0 +1,44 @@
1
+ // UI (trybuild) test: `#[upgradeable(rbac)]` compiles with UpgradeableRbac.
2
+ //
3
+ // Purpose:
4
+ // - Ensures the macro generates `impl UpgradeableRbac` when `rbac` is specified.
5
+ // - Verifies upgrade/migrate take the extra `operator` parameter.
6
+
7
+ use soroban_sdk::{contract, contractimpl, Address, Bytes, BytesN, Env};
8
+ use utils::rbac::{grant_role_no_auth, RoleBasedAccessControl};
9
+ use utils::upgradeable::{UpgradeableInternal, UPGRADER_ROLE};
10
+
11
+ #[contract]
12
+ #[common_macros::ownable]
13
+ #[common_macros::upgradeable(rbac)]
14
+ pub struct MyContract;
15
+
16
+ impl UpgradeableInternal for MyContract {
17
+ type MigrationData = ();
18
+
19
+ fn __migrate(_env: &Env, _migration_data: &Self::MigrationData) {}
20
+ }
21
+
22
+ #[contractimpl(contracttrait)]
23
+ impl RoleBasedAccessControl for MyContract {}
24
+
25
+ #[contractimpl]
26
+ impl MyContract {
27
+ pub fn init(env: Env, owner: Address) {
28
+ Self::init_owner(&env, &owner);
29
+ }
30
+
31
+ pub fn init_upgrader(env: Env, operator: Address) {
32
+ let upgrader_role = soroban_sdk::Symbol::new(&env, UPGRADER_ROLE);
33
+ grant_role_no_auth(&env, &operator, &upgrader_role, &env.current_contract_address());
34
+ }
35
+
36
+ pub fn smoke(env: Env, operator: Address) {
37
+ let hash = BytesN::<32>::from_array(&env, &[0u8; 32]);
38
+ let migration_data = Bytes::new(&env);
39
+ Self::upgrade(&env, &hash, &operator);
40
+ Self::migrate(&env, &migration_data, &operator);
41
+ }
42
+ }
43
+
44
+ fn main() {}
@@ -2,7 +2,7 @@
2
2
 
3
3
  extern crate std;
4
4
 
5
- use crate::{codec::MsgType, counter::CounterClient, tests::mint_to};
5
+ use crate::{codec::MsgType, counter::CounterClient, tests::{grant_oapp_admin, mint_to}};
6
6
  use endpoint_v2::{EndpointV2Client, MessagingFee, Origin, OutboundPacket};
7
7
  use message_lib_common::packet_codec_v1;
8
8
  use soroban_sdk::{
@@ -63,17 +63,19 @@ pub fn register_library(env: &Env, owner: &Address, endpoint: &EndpointV2Client<
63
63
 
64
64
  /// Sets the peer address for a counter on a destination EID.
65
65
  pub fn set_peer(env: &Env, owner: &Address, counter: &CounterClient<'_>, dst_eid: u32, peer: &BytesN<32>) {
66
+ grant_oapp_admin(env, &counter.address, owner);
67
+
66
68
  let peer_option = Some(peer.clone());
67
69
  env.mock_auths(&[MockAuth {
68
70
  address: owner,
69
71
  invoke: &MockAuthInvoke {
70
72
  contract: &counter.address,
71
73
  fn_name: "set_peer",
72
- args: (&dst_eid, &peer_option).into_val(env),
74
+ args: (&dst_eid, &peer_option, owner).into_val(env),
73
75
  sub_invokes: &[],
74
76
  },
75
77
  }]);
76
- counter.set_peer(&dst_eid, &peer_option);
78
+ counter.set_peer(&dst_eid, &peer_option, owner);
77
79
  }
78
80
 
79
81
  /// Decodes an outbound packet emitted by the endpoint.
@@ -4,26 +4,27 @@ use crate::{
4
4
  options,
5
5
  storage::CounterStorage,
6
6
  };
7
- use common_macros::{contract_impl, only_auth};
7
+ use common_macros::{contract_impl, lz_contract, only_auth};
8
8
  use endpoint_v2::{
9
9
  ILayerZeroComposer, LayerZeroEndpointV2Client, MessagingChannelClient, MessagingComposerClient, MessagingFee,
10
10
  Origin,
11
11
  };
12
12
  use oapp::{
13
- oapp_core::{initialize_oapp, OAppCore},
13
+ oapp_core::{init_ownable_oapp, OAppCore},
14
14
  oapp_receiver::{LzReceiveInternal, OAppReceiver},
15
15
  oapp_sender::{FeePayer, OAppSenderInternal},
16
16
  };
17
17
  use oapp_macros::oapp;
18
18
  use soroban_sdk::{assert_with_error, panic_with_error, token::TokenClient, Address, Bytes, BytesN, Env};
19
19
 
20
+ #[lz_contract]
20
21
  #[oapp(custom = [receiver])]
21
22
  pub struct Counter;
22
23
 
23
24
  #[contract_impl]
24
25
  impl Counter {
25
26
  pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address, delegate: &Address) {
26
- initialize_oapp::<Self>(env, owner, endpoint, delegate);
27
+ init_ownable_oapp::<Self>(env, owner, endpoint, delegate);
27
28
  let endpoint_client = LayerZeroEndpointV2Client::new(env, endpoint);
28
29
  CounterStorage::set_eid(env, &endpoint_client.eid());
29
30
  }
@@ -1,7 +1,8 @@
1
+ use oapp::oapp_core::OAPP_ADMIN_ROLE;
1
2
  use soroban_sdk::{
2
3
  testutils::{MockAuth, MockAuthInvoke},
3
4
  token::StellarAssetClient,
4
- Address, Env, IntoVal,
5
+ Address, Env, IntoVal, Symbol,
5
6
  };
6
7
 
7
8
  pub mod test_codec;
@@ -23,3 +24,17 @@ pub fn mint_to(env: &Env, owner: &Address, native_token: &Address, to: &Address,
23
24
  sac.mint(to, &amount);
24
25
  }
25
26
 
27
+ pub fn grant_oapp_admin(env: &Env, contract: &Address, owner: &Address) {
28
+ let role = Symbol::new(env, OAPP_ADMIN_ROLE);
29
+ env.mock_auths(&[MockAuth {
30
+ address: owner,
31
+ invoke: &MockAuthInvoke {
32
+ contract,
33
+ fn_name: "grant_role",
34
+ args: (owner, &role, owner).into_val(env),
35
+ sub_invokes: &[],
36
+ },
37
+ }]);
38
+ utils::rbac::RoleBasedAccessControlClient::new(env, contract).grant_role(owner, &role, owner);
39
+ }
40
+
@@ -88,17 +88,20 @@ fn setup<'a>() -> TestSetup<'a> {
88
88
  }
89
89
 
90
90
  fn setup_mock_peer(env: &Env, owner: &Address, counter: &CounterClient<'_>, dst_eid: u32) -> BytesN<32> {
91
+ super::grant_oapp_admin(env, &counter.address, owner);
92
+
91
93
  let peer = BytesN::from_array(env, &[1u8; 32]);
94
+ let peer_option = Some(peer.clone());
92
95
  env.mock_auths(&[MockAuth {
93
96
  address: owner,
94
97
  invoke: &MockAuthInvoke {
95
98
  contract: &counter.address,
96
99
  fn_name: "set_peer",
97
- args: (&dst_eid, &Some(peer.clone())).into_val(env),
100
+ args: (&dst_eid, &peer_option, owner).into_val(env),
98
101
  sub_invokes: &[],
99
102
  },
100
103
  }]);
101
- counter.set_peer(&dst_eid, &Some(peer.clone()));
104
+ counter.set_peer(&dst_eid, &peer_option, owner);
102
105
  peer
103
106
  }
104
107
 
@@ -1,8 +1,15 @@
1
1
  use crate::{errors::OAppError, oapp_receiver::RECEIVER_VERSION, oapp_sender::SENDER_VERSION};
2
- use common_macros::{contract_trait, only_auth, storage};
2
+ use common_macros::{contract_trait, only_role, storage};
3
3
  use endpoint_v2::LayerZeroEndpointV2Client;
4
4
  use soroban_sdk::{contractevent, Address, BytesN, Env};
5
- use utils::{option_ext::OptionExt, ownable::{Ownable, OwnableInitializer}};
5
+ use utils::{
6
+ option_ext::OptionExt,
7
+ ownable::{Ownable, OwnableInitializer},
8
+ rbac::RoleBasedAccessControl,
9
+ };
10
+
11
+ /// Role for OApp administrative actions (set_peer, set_delegate, set_enforced_options).
12
+ pub const OAPP_ADMIN_ROLE: &str = "OAPP_ADMIN_ROLE";
6
13
 
7
14
  // =====================================================
8
15
  // OAppCore Storage and Events
@@ -31,7 +38,7 @@ pub struct PeerSet {
31
38
  // =====================================================
32
39
 
33
40
  #[contract_trait]
34
- pub trait OAppCore: Ownable {
41
+ pub trait OAppCore: Ownable + RoleBasedAccessControl {
35
42
  /// Retrieves the OApp version information.
36
43
  ///
37
44
  /// # Returns
@@ -66,8 +73,14 @@ pub trait OAppCore: Ownable {
66
73
  /// # Arguments
67
74
  /// * `eid` - The endpoint ID
68
75
  /// * `peer` - The address of the peer to be associated with the corresponding endpoint, or None to remove the peer
69
- #[only_auth]
70
- fn set_peer(env: &soroban_sdk::Env, eid: u32, peer: &Option<soroban_sdk::BytesN<32>>) {
76
+ /// * `operator` - The address that must have OAPP_ADMIN_ROLE
77
+ #[only_role(operator, OAPP_ADMIN_ROLE)]
78
+ fn set_peer(
79
+ env: &soroban_sdk::Env,
80
+ eid: u32,
81
+ peer: &Option<soroban_sdk::BytesN<32>>,
82
+ operator: &soroban_sdk::Address,
83
+ ) {
71
84
  OAppCoreStorage::set_or_remove_peer(env, eid, peer);
72
85
  PeerSet { eid, peer: peer.clone() }.publish(env);
73
86
  }
@@ -76,8 +89,9 @@ pub trait OAppCore: Ownable {
76
89
  ///
77
90
  /// # Arguments
78
91
  /// * `delegate` - The address of the delegate to be set, or None to remove the delegate
79
- #[only_auth]
80
- fn set_delegate(env: &soroban_sdk::Env, delegate: &Option<soroban_sdk::Address>) {
92
+ /// * `operator` - The address that must have OAPP_ADMIN_ROLE
93
+ #[only_role(operator, OAPP_ADMIN_ROLE)]
94
+ fn set_delegate(env: &soroban_sdk::Env, delegate: &Option<soroban_sdk::Address>, operator: &soroban_sdk::Address) {
81
95
  endpoint_client::<Self>(env).set_delegate(&env.current_contract_address(), delegate);
82
96
  }
83
97
  }
@@ -96,7 +110,7 @@ pub trait OAppCore: Ownable {
96
110
  /// * `owner` - The address that will own this OApp
97
111
  /// * `endpoint` - The LayerZero endpoint address to associate with this OApp
98
112
  /// * `delegate` - The delegate address to set on the endpoint for this OApp
99
- pub fn initialize_oapp<T: OAppCore + OwnableInitializer>(
113
+ pub fn init_ownable_oapp<T: OAppCore + OwnableInitializer>(
100
114
  env: &Env,
101
115
  owner: &Address,
102
116
  endpoint: &Address,
@@ -1,7 +1,7 @@
1
- use crate::{self as oapp, errors::OAppError};
2
- use common_macros::{contract_trait, only_auth, storage};
1
+ use crate::{self as oapp, errors::OAppError, oapp_core::OAPP_ADMIN_ROLE};
2
+ use common_macros::{contract_trait, only_role, storage};
3
3
  use soroban_sdk::{assert_with_error, contractevent, contracttype, panic_with_error, Bytes, Env, Vec};
4
- use utils::{auth::Auth, buffer_reader::BufferReader};
4
+ use utils::{buffer_reader::BufferReader, rbac::RoleBasedAccessControl};
5
5
 
6
6
  pub const OPTION_TYPE3: u16 = 3;
7
7
 
@@ -30,7 +30,7 @@ pub struct EnforcedOptionSet {
30
30
  // =========================================================================
31
31
 
32
32
  #[contract_trait]
33
- pub trait OAppOptionsType3: Auth {
33
+ pub trait OAppOptionsType3: RoleBasedAccessControl {
34
34
  /// Retrieves the enforced options for a given endpoint and message type.
35
35
  ///
36
36
  /// # Arguments
@@ -53,10 +53,12 @@ pub trait OAppOptionsType3: Auth {
53
53
  ///
54
54
  /// # Arguments
55
55
  /// * `options` - A vector of EnforcedOptionParam structures specifying enforced options
56
- #[only_auth]
56
+ /// * `operator` - The address that must have OAPP_ADMIN_ROLE
57
+ #[only_role(operator, OAPP_ADMIN_ROLE)]
57
58
  fn set_enforced_options(
58
59
  env: &soroban_sdk::Env,
59
60
  options: &soroban_sdk::Vec<oapp::oapp_options_type3::EnforcedOptionParam>,
61
+ operator: &soroban_sdk::Address,
60
62
  ) {
61
63
  for param in options {
62
64
  if let Some(ref opts) = param.options {
@@ -3,3 +3,24 @@ mod oapp_options_type3;
3
3
  mod oapp_receiver;
4
4
  mod oapp_sender;
5
5
  mod test_macros;
6
+
7
+ use crate::oapp_core::OAPP_ADMIN_ROLE;
8
+ use soroban_sdk::{
9
+ testutils::{MockAuth, MockAuthInvoke},
10
+ Address, Env, IntoVal, Symbol,
11
+ };
12
+
13
+ /// Grants `OAPP_ADMIN_ROLE` to `owner` via the public `grant_role` interface.
14
+ pub(super) fn grant_oapp_admin(env: &Env, contract: &Address, owner: &Address) {
15
+ let role = Symbol::new(env, OAPP_ADMIN_ROLE);
16
+ env.mock_auths(&[MockAuth {
17
+ address: owner,
18
+ invoke: &MockAuthInvoke {
19
+ contract,
20
+ fn_name: "grant_role",
21
+ args: (owner, &role, owner).into_val(env),
22
+ sub_invokes: &[],
23
+ },
24
+ }]);
25
+ utils::rbac::RoleBasedAccessControlClient::new(env, contract).grant_role(owner, &role, owner);
26
+ }
@@ -32,6 +32,7 @@ impl DummyEndpoint {
32
32
  }
33
33
 
34
34
  #[oapp_macros::oapp]
35
+ #[common_macros::lz_contract]
35
36
  pub struct DummyOApp;
36
37
 
37
38
  impl LzReceiveInternal for DummyOApp {
@@ -51,7 +52,7 @@ impl LzReceiveInternal for DummyOApp {
51
52
  #[contractimpl]
52
53
  impl DummyOApp {
53
54
  pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address) {
54
- oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, owner);
55
+ oapp::oapp_core::init_ownable_oapp::<Self>(env, owner, endpoint, owner);
55
56
  }
56
57
  }
57
58
 
@@ -75,6 +76,8 @@ fn setup<'a>() -> TestSetup<'a> {
75
76
  let oapp = env.register(DummyOApp, (&owner, &endpoint));
76
77
  soroban_sdk::log!(&env, "oapp: {}", oapp);
77
78
  let oapp_client = DummyOAppClient::new(&env, &oapp);
79
+ super::grant_oapp_admin(&env, &oapp, &owner);
80
+
78
81
  TestSetup { env, owner, endpoint, oapp_client }
79
82
  }
80
83
 
@@ -90,11 +93,11 @@ fn set_peer_with_auth(
90
93
  invoke: &MockAuthInvoke {
91
94
  contract: &oapp_client.address,
92
95
  fn_name: "set_peer",
93
- args: (&eid, peer).into_val(env),
96
+ args: (&eid, peer, signer).into_val(env),
94
97
  sub_invokes: &[],
95
98
  },
96
99
  }]);
97
- oapp_client.set_peer(&eid, peer);
100
+ oapp_client.set_peer(&eid, peer, signer);
98
101
  }
99
102
 
100
103
  fn set_delegate_with_auth(env: &Env, signer: &Address, oapp_client: &DummyOAppClient<'_>, delegate: &Option<Address>) {
@@ -103,11 +106,11 @@ fn set_delegate_with_auth(env: &Env, signer: &Address, oapp_client: &DummyOAppCl
103
106
  invoke: &MockAuthInvoke {
104
107
  contract: &oapp_client.address,
105
108
  fn_name: "set_delegate",
106
- args: (delegate,).into_val(env),
109
+ args: (delegate, signer).into_val(env),
107
110
  sub_invokes: &[],
108
111
  },
109
112
  }]);
110
- oapp_client.set_delegate(delegate);
113
+ oapp_client.set_delegate(delegate, signer);
111
114
  }
112
115
 
113
116
  #[test]
@@ -166,14 +169,14 @@ fn test_peer_lifecycle_set_get_update_remove_and_events() {
166
169
  #[test]
167
170
  #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
168
171
  fn test_set_peer_unauthorized() {
169
- let TestSetup { env, oapp_client, .. } = setup();
172
+ let TestSetup { env, owner, oapp_client, .. } = setup();
170
173
 
171
174
  let test_peer: BytesN<32> = BytesN::from_array(&env, &[33; 32]);
172
- oapp_client.set_peer(&REMOTE_EID, &Some(test_peer));
175
+ oapp_client.set_peer(&REMOTE_EID, &Some(test_peer), &owner);
173
176
  }
174
177
 
175
178
  #[test]
176
- #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
179
+ #[should_panic(expected = "Error(Contract, #1086)")] // RbacError::Unauthorized
177
180
  fn test_set_peer_non_owner_authorized() {
178
181
  let TestSetup { env, owner, oapp_client, .. } = setup();
179
182
  let non_owner = Address::generate(&env);
@@ -204,14 +207,14 @@ fn test_set_delegate_updates_and_clears_endpoint_delegate() {
204
207
  #[test]
205
208
  #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
206
209
  fn test_set_delegate_unauthorized() {
207
- let TestSetup { env, oapp_client, .. } = setup();
210
+ let TestSetup { env, owner, oapp_client, .. } = setup();
208
211
 
209
212
  let delegate = Address::generate(&env);
210
- oapp_client.set_delegate(&Some(delegate));
213
+ oapp_client.set_delegate(&Some(delegate), &owner);
211
214
  }
212
215
 
213
216
  #[test]
214
- #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
217
+ #[should_panic(expected = "Error(Contract, #1086)")] // RbacError::Unauthorized
215
218
  fn test_set_delegate_non_owner_authorized() {
216
219
  let TestSetup { env, owner, oapp_client, .. } = setup();
217
220
  let non_owner = Address::generate(&env);
@@ -30,8 +30,12 @@ impl DummyEndpoint {
30
30
  }
31
31
 
32
32
  #[oapp_macros::oapp(custom = [core, sender, receiver])]
33
+ #[common_macros::lz_contract]
33
34
  pub struct DummyOAppOptionsType3;
34
35
 
36
+ #[contract_impl(contracttrait)]
37
+ impl utils::rbac::RoleBasedAccessControl for DummyOAppOptionsType3 {}
38
+
35
39
  #[contract_impl(contracttrait)]
36
40
  impl OAppCore for DummyOAppOptionsType3 {}
37
41
 
@@ -55,7 +59,7 @@ impl OAppReceiver for DummyOAppOptionsType3 {}
55
59
  #[contract_impl]
56
60
  impl DummyOAppOptionsType3 {
57
61
  pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address, delegate: &Address) {
58
- oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, delegate);
62
+ oapp::oapp_core::init_ownable_oapp::<Self>(env, owner, endpoint, delegate);
59
63
  }
60
64
  }
61
65
 
@@ -73,6 +77,7 @@ fn setup<'a>() -> TestSetup<'a> {
73
77
  let delegate = owner.clone();
74
78
  let oapp = env.register(DummyOAppOptionsType3, (&owner, &endpoint, &delegate));
75
79
  let oapp_client = DummyOAppOptionsType3Client::new(&env, &oapp);
80
+ super::grant_oapp_admin(&env, &oapp, &owner);
76
81
 
77
82
  TestSetup { env, owner, oapp_client }
78
83
  }
@@ -94,11 +99,11 @@ fn set_enforced_options_with_auth(
94
99
  invoke: &MockAuthInvoke {
95
100
  contract: &oapp_client.address,
96
101
  fn_name: "set_enforced_options",
97
- args: (enforced_params,).into_val(env),
102
+ args: (enforced_params, signer).into_val(env),
98
103
  sub_invokes: &[],
99
104
  },
100
105
  }]);
101
- oapp_client.set_enforced_options(enforced_params);
106
+ oapp_client.set_enforced_options(enforced_params, signer);
102
107
  }
103
108
 
104
109
  #[test]
@@ -164,16 +169,16 @@ fn test_combine_options() {
164
169
  #[test]
165
170
  #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
166
171
  fn test_set_enforced_options_unauthorized() {
167
- let TestSetup { env, oapp_client, .. } = setup();
172
+ let TestSetup { env, owner, oapp_client, .. } = setup();
168
173
 
169
174
  let options = create_valid_options(&env, &[1, 2, 3, 4]);
170
175
  let enforced_params =
171
176
  vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: Some(options.clone()) }];
172
- oapp_client.set_enforced_options(&enforced_params);
177
+ oapp_client.set_enforced_options(&enforced_params, &owner);
173
178
  }
174
179
 
175
180
  #[test]
176
- #[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
181
+ #[should_panic(expected = "Error(Contract, #1086)")] // RbacError::Unauthorized
177
182
  fn test_set_enforced_options_non_owner_authorized() {
178
183
  let TestSetup { env, owner, oapp_client, .. } = setup();
179
184
  let non_owner = Address::generate(&env);
@@ -202,11 +207,11 @@ fn test_set_enforced_options_invalid_options_returns_error() {
202
207
  invoke: &MockAuthInvoke {
203
208
  contract: &oapp_client.address,
204
209
  fn_name: "set_enforced_options",
205
- args: (&enforced_params,).into_val(&env),
210
+ args: (&enforced_params, &owner).into_val(&env),
206
211
  sub_invokes: &[],
207
212
  },
208
213
  }]);
209
- let result = oapp_client.try_set_enforced_options(&enforced_params);
214
+ let result = oapp_client.try_set_enforced_options(&enforced_params, &owner);
210
215
  assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::InvalidOptions.into());
211
216
  }
212
217
 
@@ -215,7 +220,8 @@ fn test_combine_options_extra_invalid_type_returns_error_when_enforced_present()
215
220
  let TestSetup { env, owner, oapp_client, .. } = setup();
216
221
 
217
222
  let enforced = create_valid_options(&env, &[1, 2, 3]);
218
- let params = vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: Some(enforced) }];
223
+ let params =
224
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: Some(enforced) }];
219
225
  set_enforced_options_with_auth(&env, &owner, &oapp_client, &params);
220
226
 
221
227
  // extra has wrong option type (not 3) but len >= 2 -> validated and should panic
@@ -230,7 +236,8 @@ fn test_combine_options_extra_too_short_returns_error_when_enforced_present() {
230
236
  let TestSetup { env, owner, oapp_client, .. } = setup();
231
237
 
232
238
  let enforced = create_valid_options(&env, &[1, 2, 3]);
233
- let params = vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: Some(enforced) }];
239
+ let params =
240
+ vec![&env, EnforcedOptionParam { eid: REMOTE_EID_1, msg_type: MSG_TYPE_SEND, options: Some(enforced) }];
234
241
  set_enforced_options_with_auth(&env, &owner, &oapp_client, &params);
235
242
 
236
243
  // extra is non-empty but len < 2 -> should panic
@@ -8,6 +8,7 @@ use soroban_sdk::{
8
8
  };
9
9
 
10
10
  #[oapp_macros::oapp]
11
+ #[common_macros::lz_contract]
11
12
  pub struct DummyOAppReceiver;
12
13
 
13
14
  impl LzReceiveInternal for DummyOAppReceiver {
@@ -27,7 +28,7 @@ impl LzReceiveInternal for DummyOAppReceiver {
27
28
  #[contractimpl]
28
29
  impl DummyOAppReceiver {
29
30
  pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address) {
30
- oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, owner);
31
+ oapp::oapp_core::init_ownable_oapp::<Self>(env, owner, endpoint, owner);
31
32
  }
32
33
  }
33
34
 
@@ -95,6 +96,8 @@ fn setup<'a>() -> TestSetup<'a> {
95
96
  let endpoint = env.register(MockEndpoint, (&native_token,));
96
97
  let oapp = env.register(DummyOAppReceiver, (&owner, &endpoint));
97
98
  let oapp_client = DummyOAppReceiverClient::new(&env, &oapp);
99
+ super::grant_oapp_admin(&env, &oapp, &owner);
100
+
98
101
  TestSetup { env, owner, endpoint, token_admin, native_token, native_token_admin_client, oapp_client }
99
102
  }
100
103
 
@@ -105,11 +108,11 @@ fn set_peer(env: &Env, owner: &Address, oapp_client: &DummyOAppReceiverClient<'_
105
108
  invoke: &MockAuthInvoke {
106
109
  contract: &oapp_client.address,
107
110
  fn_name: "set_peer",
108
- args: (&eid, &peer_option).into_val(env),
111
+ args: (&eid, &peer_option, owner).into_val(env),
109
112
  sub_invokes: &[],
110
113
  },
111
114
  }]);
112
- oapp_client.set_peer(&eid, &peer_option);
115
+ oapp_client.set_peer(&eid, &peer_option, owner);
113
116
  }
114
117
 
115
118
  fn lz_receive(
@@ -64,6 +64,7 @@ impl MockEndpoint {
64
64
  }
65
65
 
66
66
  #[oapp_macros::oapp]
67
+ #[common_macros::lz_contract]
67
68
  pub struct DummyOAppSender;
68
69
 
69
70
  impl LzReceiveInternal for DummyOAppSender {
@@ -83,7 +84,7 @@ impl LzReceiveInternal for DummyOAppSender {
83
84
  #[contractimpl]
84
85
  impl DummyOAppSender {
85
86
  pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address) {
86
- oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, owner);
87
+ oapp::oapp_core::init_ownable_oapp::<Self>(env, owner, endpoint, owner);
87
88
  }
88
89
 
89
90
  pub fn quote(env: &Env, dst_eid: u32, message: &Bytes, options: &Bytes, pay_in_zro: bool) -> MessagingFee {
@@ -152,6 +153,7 @@ fn setup<'a>() -> TestSetup<'a> {
152
153
  // Deploy OApp
153
154
  let oapp = env.register(DummyOAppSender, (&owner, &endpoint));
154
155
  let oapp_client = DummyOAppSenderClient::new(&env, &oapp);
156
+ super::grant_oapp_admin(&env, &oapp, &owner);
155
157
 
156
158
  TestSetup {
157
159
  env,
@@ -180,11 +182,11 @@ fn set_peer_with_auth(
180
182
  invoke: &MockAuthInvoke {
181
183
  contract: &oapp_client.address,
182
184
  fn_name: "set_peer",
183
- args: (&eid, &peer_option).into_val(env),
185
+ args: (&eid, &peer_option, owner).into_val(env),
184
186
  sub_invokes: &[],
185
187
  },
186
188
  }]);
187
- oapp_client.set_peer(&eid, &peer_option);
189
+ oapp_client.set_peer(&eid, &peer_option, owner);
188
190
  }
189
191
 
190
192
  fn mint_to(
@@ -10,6 +10,7 @@ mod test_full_default {
10
10
  use soroban_sdk::{Address, Bytes, BytesN, Env};
11
11
 
12
12
  #[oapp]
13
+ #[common_macros::lz_contract]
13
14
  struct TestFullDefault;
14
15
 
15
16
  impl LzReceiveInternal for TestFullDefault {
@@ -40,8 +41,12 @@ mod test_full_manual_core {
40
41
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
41
42
 
42
43
  #[oapp(custom = [core])]
44
+ #[common_macros::lz_contract]
43
45
  struct TestFullManualCore;
44
46
 
47
+ #[soroban_sdk::contractimpl(contracttrait)]
48
+ impl utils::rbac::RoleBasedAccessControl for TestFullManualCore {}
49
+
45
50
  #[contractimpl(contracttrait)]
46
51
  impl OAppCore for TestFullManualCore {
47
52
  fn oapp_version(_env: &Env) -> (u64, u64) {
@@ -77,6 +82,7 @@ mod test_full_manual_sender {
77
82
  use soroban_sdk::{Address, Bytes, BytesN, Env};
78
83
 
79
84
  #[oapp(custom = [sender])]
85
+ #[common_macros::lz_contract]
80
86
  struct TestFullManualSender;
81
87
 
82
88
  impl OAppSenderInternal for TestFullManualSender {
@@ -110,6 +116,7 @@ mod test_full_manual_receiver {
110
116
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
111
117
 
112
118
  #[oapp(custom = [receiver])]
119
+ #[common_macros::lz_contract]
113
120
  struct TestFullManualReceiver;
114
121
 
115
122
  impl LzReceiveInternal for TestFullManualReceiver {
@@ -155,6 +162,7 @@ mod test_full_manual_options {
155
162
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
156
163
 
157
164
  #[oapp(custom = [options_type3])]
165
+ #[common_macros::lz_contract]
158
166
  struct TestFullManualOptions;
159
167
 
160
168
  impl LzReceiveInternal for TestFullManualOptions {
@@ -189,8 +197,12 @@ mod test_full_manual_core_sender {
189
197
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
190
198
 
191
199
  #[oapp(custom = [core, sender])]
200
+ #[common_macros::lz_contract]
192
201
  struct TestFullManualCoreSender;
193
202
 
203
+ #[soroban_sdk::contractimpl(contracttrait)]
204
+ impl utils::rbac::RoleBasedAccessControl for TestFullManualCoreSender {}
205
+
194
206
  #[contractimpl(contracttrait)]
195
207
  impl OAppCore for TestFullManualCoreSender {
196
208
  fn oapp_version(_env: &Env) -> (u64, u64) {
@@ -232,8 +244,12 @@ mod test_full_manual_core_receiver {
232
244
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
233
245
 
234
246
  #[oapp(custom = [core, receiver])]
247
+ #[common_macros::lz_contract]
235
248
  struct TestFullManualCoreReceiver;
236
249
 
250
+ #[soroban_sdk::contractimpl(contracttrait)]
251
+ impl utils::rbac::RoleBasedAccessControl for TestFullManualCoreReceiver {}
252
+
237
253
  #[contractimpl(contracttrait)]
238
254
  impl OAppCore for TestFullManualCoreReceiver {
239
255
  fn oapp_version(_env: &Env) -> (u64, u64) {
@@ -274,6 +290,7 @@ mod test_full_manual_sender_receiver {
274
290
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
275
291
 
276
292
  #[oapp(custom = [sender, receiver])]
293
+ #[common_macros::lz_contract]
277
294
  struct TestFullManualSenderReceiver;
278
295
 
279
296
  impl OAppSenderInternal for TestFullManualSenderReceiver {
@@ -314,8 +331,12 @@ mod test_full_manual_all_except_options {
314
331
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
315
332
 
316
333
  #[oapp(custom = [core, sender, receiver])]
334
+ #[common_macros::lz_contract]
317
335
  struct TestFullManualAllExceptOptions;
318
336
 
337
+ #[soroban_sdk::contractimpl(contracttrait)]
338
+ impl utils::rbac::RoleBasedAccessControl for TestFullManualAllExceptOptions {}
339
+
319
340
  #[contractimpl(contracttrait)]
320
341
  impl OAppCore for TestFullManualAllExceptOptions {
321
342
  fn oapp_version(_env: &Env) -> (u64, u64) {
@@ -362,8 +383,12 @@ mod test_full_manual_all {
362
383
  use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};
363
384
 
364
385
  #[oapp(custom = [core, sender, receiver, options_type3])]
386
+ #[common_macros::lz_contract]
365
387
  struct TestFullManualAll;
366
388
 
389
+ #[soroban_sdk::contractimpl(contracttrait)]
390
+ impl utils::rbac::RoleBasedAccessControl for TestFullManualAll {}
391
+
367
392
  #[contractimpl(contracttrait)]
368
393
  impl OAppCore for TestFullManualAll {
369
394
  fn oapp_version(_env: &Env) -> (u64, u64) {