@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.
- package/.turbo/turbo-build.log +312 -397
- package/.turbo/turbo-lint.log +185 -245
- package/.turbo/turbo-test.log +1846 -1942
- package/Cargo.lock +22 -127
- package/Cargo.toml +4 -6
- package/contracts/common-macros/src/lib.rs +38 -15
- package/contracts/common-macros/src/lz_contract.rs +12 -21
- package/contracts/common-macros/src/tests/lz_contract.rs +17 -8
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__lz_contract__snapshot_generated_lz_contract_code.snap +20 -0
- package/contracts/common-macros/src/upgradeable.rs +37 -30
- package/contracts/endpoint-v2/src/endpoint_v2.rs +4 -3
- package/contracts/endpoint-v2/src/errors.rs +2 -2
- package/contracts/endpoint-v2/src/messaging_channel.rs +11 -0
- package/contracts/endpoint-v2/src/messaging_composer.rs +1 -0
- package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +12 -25
- package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +4 -4
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +50 -10
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +6 -35
- package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +2 -2
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +50 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +78 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/insert_and_drain_pending_nonces.rs +272 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +1 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +10 -5
- package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +30 -0
- package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +25 -6
- package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +13 -11
- package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +13 -10
- package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +15 -11
- package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +5 -3
- package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +1 -1
- package/contracts/macro-integration-tests/tests/runtime/ownable/two_step_transfer.rs +14 -12
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +3 -9
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_invalid_inner_option.stderr +24 -1
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +3 -3
- package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/upgradeable_rbac.rs +44 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_auth_trait.rs +28 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_auth_trait.stderr +397 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +1 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +10 -10
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +4 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +7 -0
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +5 -4
- package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +2 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/basic.rs +1 -1
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/attr_args.stderr +1 -1
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +2 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +2 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/rbac.rs +44 -0
- package/contracts/oapps/counter/integration_tests/utils.rs +5 -3
- package/contracts/oapps/counter/src/counter.rs +4 -3
- package/contracts/oapps/counter/src/tests/mod.rs +16 -1
- package/contracts/oapps/counter/src/tests/test_counter.rs +5 -2
- package/contracts/oapps/oapp/src/oapp_core.rs +22 -8
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +7 -5
- package/contracts/oapps/oapp/src/tests/mod.rs +21 -0
- package/contracts/oapps/oapp/src/tests/oapp_core.rs +14 -11
- package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +17 -10
- package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +6 -3
- package/contracts/oapps/oapp/src/tests/oapp_sender.rs +5 -3
- package/contracts/oapps/oapp/src/tests/test_macros.rs +25 -0
- package/contracts/oapps/oapp-macros/src/generators.rs +12 -9
- package/contracts/oapps/oapp-macros/src/lib.rs +1 -1
- package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +15 -7
- package/contracts/oapps/oft/integration-tests/setup.rs +22 -4
- package/contracts/oapps/oft/integration-tests/utils.rs +94 -13
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +23 -10
- package/contracts/oapps/oft/src/extensions/pausable.rs +31 -10
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +9 -4
- package/contracts/oapps/oft/src/oft.rs +3 -3
- package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +39 -27
- package/contracts/oapps/oft/src/tests/extensions/pausable.rs +38 -24
- package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +87 -69
- package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +1 -0
- package/contracts/oapps/oft-core/integration-tests/setup.rs +28 -3
- package/contracts/oapps/oft-core/src/oft_core.rs +11 -6
- package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +20 -20
- package/contracts/oapps/oft-core/src/tests/test_utils.rs +33 -3
- package/contracts/upgrader/src/lib.rs +67 -30
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract3.wasm +0 -0
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract4.wasm +0 -0
- package/contracts/upgrader/src/tests/test_upgrader.rs +50 -4
- package/contracts/utils/src/ownable.rs +16 -5
- package/contracts/utils/src/tests/ownable.rs +39 -39
- package/contracts/utils/src/upgradeable.rs +60 -17
- package/docs/oapp-guide.md +18 -13
- package/package.json +5 -5
- package/sdk/.turbo/turbo-test.log +359 -348
- package/sdk/dist/generated/bml.d.ts +4 -4
- package/sdk/dist/generated/bml.js +6 -6
- package/sdk/dist/generated/counter.d.ts +269 -123
- package/sdk/dist/generated/counter.js +45 -25
- package/sdk/dist/generated/dvn.d.ts +4 -6
- package/sdk/dist/generated/dvn.js +8 -8
- package/sdk/dist/generated/dvn_fee_lib.d.ts +8 -10
- package/sdk/dist/generated/dvn_fee_lib.js +8 -8
- package/sdk/dist/generated/endpoint.d.ts +9 -9
- package/sdk/dist/generated/endpoint.js +9 -9
- package/sdk/dist/generated/executor.d.ts +9 -11
- package/sdk/dist/generated/executor.js +11 -11
- package/sdk/dist/generated/executor_fee_lib.d.ts +9 -11
- package/sdk/dist/generated/executor_fee_lib.js +11 -11
- package/sdk/dist/generated/executor_helper.d.ts +4 -4
- package/sdk/dist/generated/executor_helper.js +6 -6
- package/sdk/dist/generated/layerzero_view.d.ts +9 -11
- package/sdk/dist/generated/layerzero_view.js +11 -11
- package/sdk/dist/generated/oft.d.ts +323 -156
- package/sdk/dist/generated/oft.js +65 -43
- package/sdk/dist/generated/price_feed.d.ts +8 -10
- package/sdk/dist/generated/price_feed.js +8 -8
- package/sdk/dist/generated/sac_manager.d.ts +8 -8
- package/sdk/dist/generated/sac_manager.js +6 -6
- package/sdk/dist/generated/sml.d.ts +9 -9
- package/sdk/dist/generated/sml.js +9 -9
- package/sdk/dist/generated/treasury.d.ts +9 -9
- package/sdk/dist/generated/treasury.js +9 -9
- package/sdk/dist/generated/uln302.d.ts +9 -9
- package/sdk/dist/generated/uln302.js +9 -9
- package/sdk/dist/generated/upgrader.d.ts +25 -16
- package/sdk/dist/generated/upgrader.js +5 -5
- package/sdk/package.json +1 -1
- package/sdk/test/counter-sml.test.ts +20 -0
- package/sdk/test/counter-uln.test.ts +20 -0
- package/sdk/test/oft-sml.test.ts +22 -0
- package/sdk/test/upgrader.test.ts +1 -0
- package/ts-bindings-gen.toml +67 -0
- package/turbo.json +1 -8
- package/tools/ts-bindings-gen/Cargo.toml +0 -16
- package/tools/ts-bindings-gen/src/main.rs +0 -214
|
@@ -65,15 +65,13 @@ impl Parse for CustomImpls {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
/// Generates
|
|
68
|
+
/// Generates OApp trait implementations only. No contract-level attributes are applied.
|
|
69
69
|
///
|
|
70
|
-
/// This function creates
|
|
71
|
-
///
|
|
72
|
-
///
|
|
73
|
-
///
|
|
74
|
-
///
|
|
75
|
-
/// - `#[common_macros::ownable]` - Adds single-owner access control
|
|
76
|
-
/// - OAppCore, OAppSenderInternal, OAppReceiver, and OAppOptionsType3 trait implementations
|
|
70
|
+
/// This function creates OAppCore, OAppSenderInternal, OAppReceiver, and OAppOptionsType3 trait implementations.
|
|
71
|
+
///
|
|
72
|
+
/// **The user must apply a contract macro** such as `#[common_macros::lz_contract]` or
|
|
73
|
+
/// `#[soroban_sdk::contract]` to the struct. `#[lz_contract]` provides contract, TTL, and Auth
|
|
74
|
+
/// (via `#[ownable]` or `#[multisig]`) in one place.
|
|
77
75
|
///
|
|
78
76
|
/// The `custom` parameter controls which trait implementations are generated vs.
|
|
79
77
|
/// expected to be provided by the user.
|
|
@@ -86,7 +84,6 @@ pub fn generate_oapp(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|
|
86
84
|
let receiver_impl = (!custom.receiver).then(|| generate_oapp_receiver(&item_struct.ident));
|
|
87
85
|
let options_type3_impl = (!custom.options_type3).then(|| generate_oapp_options_type3(&item_struct.ident));
|
|
88
86
|
quote! {
|
|
89
|
-
#[common_macros::lz_contract]
|
|
90
87
|
#item_struct
|
|
91
88
|
|
|
92
89
|
#core_impl
|
|
@@ -98,12 +95,18 @@ pub fn generate_oapp(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|
|
98
95
|
|
|
99
96
|
/// Generates an empty `impl OAppCore` that uses the trait's default implementations
|
|
100
97
|
/// for peer management and endpoint access.
|
|
98
|
+
///
|
|
99
|
+
/// Also generates `impl RoleBasedAccessControl` because OAppCore extends it.
|
|
101
100
|
fn generate_oapp_core(name: &Ident) -> TokenStream {
|
|
102
101
|
quote! {
|
|
103
102
|
use oapp::oapp_core::OAppCore as _;
|
|
103
|
+
use utils::rbac::RoleBasedAccessControl as _;
|
|
104
104
|
|
|
105
105
|
#[soroban_sdk::contractimpl(contracttrait)]
|
|
106
106
|
impl oapp::oapp_core::OAppCore for #name {}
|
|
107
|
+
|
|
108
|
+
#[soroban_sdk::contractimpl(contracttrait)]
|
|
109
|
+
impl utils::rbac::RoleBasedAccessControl for #name {}
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
|
|
@@ -126,7 +126,7 @@ mod generators;
|
|
|
126
126
|
|
|
127
127
|
use proc_macro::TokenStream;
|
|
128
128
|
|
|
129
|
-
/// Derives
|
|
129
|
+
/// Derives OApp trait implementations. Apply `#[lz_contract]` (or similar) for contract + TTL + Auth.
|
|
130
130
|
///
|
|
131
131
|
/// ## Usage
|
|
132
132
|
///
|
|
@@ -5,11 +5,13 @@ expression: combined
|
|
|
5
5
|
---
|
|
6
6
|
// === Default (no custom impls) ===
|
|
7
7
|
|
|
8
|
-
#[common_macros::lz_contract]
|
|
9
8
|
pub struct MyOApp;
|
|
10
9
|
use oapp::oapp_core::OAppCore as _;
|
|
10
|
+
use utils::rbac::RoleBasedAccessControl as _;
|
|
11
11
|
#[soroban_sdk::contractimpl(contracttrait)]
|
|
12
12
|
impl oapp::oapp_core::OAppCore for MyOApp {}
|
|
13
|
+
#[soroban_sdk::contractimpl(contracttrait)]
|
|
14
|
+
impl utils::rbac::RoleBasedAccessControl for MyOApp {}
|
|
13
15
|
use oapp::oapp_sender::OAppSenderInternal as _;
|
|
14
16
|
impl oapp::oapp_sender::OAppSenderInternal for MyOApp {}
|
|
15
17
|
use oapp::oapp_receiver::OAppReceiver as _;
|
|
@@ -22,7 +24,6 @@ impl oapp::oapp_options_type3::OAppOptionsType3 for MyOApp {}
|
|
|
22
24
|
|
|
23
25
|
// === custom = [core] ===
|
|
24
26
|
|
|
25
|
-
#[common_macros::lz_contract]
|
|
26
27
|
pub struct MyOApp;
|
|
27
28
|
use oapp::oapp_sender::OAppSenderInternal as _;
|
|
28
29
|
impl oapp::oapp_sender::OAppSenderInternal for MyOApp {}
|
|
@@ -36,11 +37,13 @@ impl oapp::oapp_options_type3::OAppOptionsType3 for MyOApp {}
|
|
|
36
37
|
|
|
37
38
|
// === custom = [sender] ===
|
|
38
39
|
|
|
39
|
-
#[common_macros::lz_contract]
|
|
40
40
|
pub struct MyOApp;
|
|
41
41
|
use oapp::oapp_core::OAppCore as _;
|
|
42
|
+
use utils::rbac::RoleBasedAccessControl as _;
|
|
42
43
|
#[soroban_sdk::contractimpl(contracttrait)]
|
|
43
44
|
impl oapp::oapp_core::OAppCore for MyOApp {}
|
|
45
|
+
#[soroban_sdk::contractimpl(contracttrait)]
|
|
46
|
+
impl utils::rbac::RoleBasedAccessControl for MyOApp {}
|
|
44
47
|
use oapp::oapp_receiver::OAppReceiver as _;
|
|
45
48
|
#[soroban_sdk::contractimpl(contracttrait)]
|
|
46
49
|
impl oapp::oapp_receiver::OAppReceiver for MyOApp {}
|
|
@@ -51,11 +54,13 @@ impl oapp::oapp_options_type3::OAppOptionsType3 for MyOApp {}
|
|
|
51
54
|
|
|
52
55
|
// === custom = [receiver] ===
|
|
53
56
|
|
|
54
|
-
#[common_macros::lz_contract]
|
|
55
57
|
pub struct MyOApp;
|
|
56
58
|
use oapp::oapp_core::OAppCore as _;
|
|
59
|
+
use utils::rbac::RoleBasedAccessControl as _;
|
|
57
60
|
#[soroban_sdk::contractimpl(contracttrait)]
|
|
58
61
|
impl oapp::oapp_core::OAppCore for MyOApp {}
|
|
62
|
+
#[soroban_sdk::contractimpl(contracttrait)]
|
|
63
|
+
impl utils::rbac::RoleBasedAccessControl for MyOApp {}
|
|
59
64
|
use oapp::oapp_sender::OAppSenderInternal as _;
|
|
60
65
|
impl oapp::oapp_sender::OAppSenderInternal for MyOApp {}
|
|
61
66
|
use oapp::oapp_options_type3::OAppOptionsType3 as _;
|
|
@@ -65,11 +70,13 @@ impl oapp::oapp_options_type3::OAppOptionsType3 for MyOApp {}
|
|
|
65
70
|
|
|
66
71
|
// === custom = [options_type3] ===
|
|
67
72
|
|
|
68
|
-
#[common_macros::lz_contract]
|
|
69
73
|
pub struct MyOApp;
|
|
70
74
|
use oapp::oapp_core::OAppCore as _;
|
|
75
|
+
use utils::rbac::RoleBasedAccessControl as _;
|
|
71
76
|
#[soroban_sdk::contractimpl(contracttrait)]
|
|
72
77
|
impl oapp::oapp_core::OAppCore for MyOApp {}
|
|
78
|
+
#[soroban_sdk::contractimpl(contracttrait)]
|
|
79
|
+
impl utils::rbac::RoleBasedAccessControl for MyOApp {}
|
|
73
80
|
use oapp::oapp_sender::OAppSenderInternal as _;
|
|
74
81
|
impl oapp::oapp_sender::OAppSenderInternal for MyOApp {}
|
|
75
82
|
use oapp::oapp_receiver::OAppReceiver as _;
|
|
@@ -79,20 +86,21 @@ impl oapp::oapp_receiver::OAppReceiver for MyOApp {}
|
|
|
79
86
|
|
|
80
87
|
// === custom = [core, sender, receiver, options_type3] ===
|
|
81
88
|
|
|
82
|
-
#[common_macros::lz_contract]
|
|
83
89
|
pub struct MyOApp;
|
|
84
90
|
|
|
85
91
|
|
|
86
92
|
// === Struct attributes + fields are preserved ===
|
|
87
93
|
|
|
88
|
-
#[common_macros::lz_contract]
|
|
89
94
|
#[derive(Clone, Debug)]
|
|
90
95
|
pub struct FancyOApp {
|
|
91
96
|
pub x: u32,
|
|
92
97
|
}
|
|
93
98
|
use oapp::oapp_core::OAppCore as _;
|
|
99
|
+
use utils::rbac::RoleBasedAccessControl as _;
|
|
94
100
|
#[soroban_sdk::contractimpl(contracttrait)]
|
|
95
101
|
impl oapp::oapp_core::OAppCore for FancyOApp {}
|
|
102
|
+
#[soroban_sdk::contractimpl(contracttrait)]
|
|
103
|
+
impl utils::rbac::RoleBasedAccessControl for FancyOApp {}
|
|
96
104
|
use oapp::oapp_sender::OAppSenderInternal as _;
|
|
97
105
|
impl oapp::oapp_sender::OAppSenderInternal for FancyOApp {}
|
|
98
106
|
use oapp::oapp_receiver::OAppReceiver as _;
|
|
@@ -10,12 +10,13 @@ use crate::{
|
|
|
10
10
|
oft_types::OftType,
|
|
11
11
|
};
|
|
12
12
|
use endpoint_v2::{EndpointV2, EndpointV2Client};
|
|
13
|
+
use oapp::oapp_core::OAPP_ADMIN_ROLE;
|
|
13
14
|
use simple_message_lib::{SimpleMessageLib, SimpleMessageLibClient};
|
|
14
15
|
use soroban_sdk::{
|
|
15
16
|
contract, contractimpl, contracttype, log,
|
|
16
17
|
testutils::{Address as _, MockAuth, MockAuthInvoke},
|
|
17
18
|
token::{StellarAssetClient, TokenClient},
|
|
18
|
-
Address, BytesN, Env, IntoVal,
|
|
19
|
+
Address, BytesN, Env, IntoVal, Symbol,
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
// ============================================================================
|
|
@@ -126,7 +127,7 @@ fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
|
|
|
126
127
|
let shared_decimals: u32 = 6; // Default shared decimals
|
|
127
128
|
// MintBurn with SAC wrapper: OFT uses wrapper for mint on credit; burn is on token directly.
|
|
128
129
|
let mode = OftType::MintBurn(sac_wrapper_address.clone());
|
|
129
|
-
let oft_address = env.register(OFT, (&oft_token, &shared_decimals, &mode, &
|
|
130
|
+
let oft_address = env.register(OFT, (&oft_token, &shared_decimals, &mode, &endpoint_address, delegate.as_ref().unwrap()));
|
|
130
131
|
|
|
131
132
|
let endpoint = EndpointV2Client::new(env, &endpoint_address);
|
|
132
133
|
let sml = SimpleMessageLibClient::new(env, &sml_address);
|
|
@@ -213,17 +214,34 @@ pub fn wire_oft(env: &Env, chains: &[&ChainSetup<'_>]) {
|
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
216
|
|
|
217
|
+
fn grant_oapp_admin(env: &Env, contract: &Address, owner: &Address) {
|
|
218
|
+
let role = Symbol::new(env, OAPP_ADMIN_ROLE);
|
|
219
|
+
env.mock_auths(&[MockAuth {
|
|
220
|
+
address: owner,
|
|
221
|
+
invoke: &MockAuthInvoke {
|
|
222
|
+
contract,
|
|
223
|
+
fn_name: "grant_role",
|
|
224
|
+
args: (owner, &role, owner).into_val(env),
|
|
225
|
+
sub_invokes: &[],
|
|
226
|
+
},
|
|
227
|
+
}]);
|
|
228
|
+
utils::rbac::RoleBasedAccessControlClient::new(env, contract).grant_role(owner, &role, owner);
|
|
229
|
+
}
|
|
230
|
+
|
|
216
231
|
pub fn set_peer(env: &Env, owner: &Address, oft: &OFTClient<'_>, dst_eid: u32, peer: &BytesN<32>) {
|
|
232
|
+
grant_oapp_admin(env, &oft.address, owner);
|
|
233
|
+
|
|
234
|
+
let peer_option = Some(peer.clone());
|
|
217
235
|
env.mock_auths(&[MockAuth {
|
|
218
236
|
address: owner,
|
|
219
237
|
invoke: &MockAuthInvoke {
|
|
220
238
|
contract: &oft.address,
|
|
221
239
|
fn_name: "set_peer",
|
|
222
|
-
args: (&dst_eid, &
|
|
240
|
+
args: (&dst_eid, &peer_option, owner).into_val(env),
|
|
223
241
|
sub_invokes: &[],
|
|
224
242
|
},
|
|
225
243
|
}]);
|
|
226
|
-
oapp::oapp_core::OAppCoreClient::new(env, &oft.address).set_peer(&dst_eid, &
|
|
244
|
+
oapp::oapp_core::OAppCoreClient::new(env, &oft.address).set_peer(&dst_eid, &peer_option, owner);
|
|
227
245
|
}
|
|
228
246
|
|
|
229
247
|
pub fn register_library(env: &Env, owner: &Address, endpoint: &EndpointV2Client<'_>, lib: &Address) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
//! Utility functions for OFT-STD integration tests.
|
|
2
2
|
|
|
3
|
-
use crate::extensions::rate_limiter::{Direction, Mode, RateLimitConfig};
|
|
3
|
+
use crate::extensions::rate_limiter::{Direction, Mode, RateLimitConfig, RATE_LIMITER_ADMIN_ROLE};
|
|
4
|
+
use crate::extensions::oft_fee::FEE_ADMIN_ROLE;
|
|
5
|
+
use crate::extensions::pausable::{PAUSER_ROLE, UNPAUSER_ROLE};
|
|
4
6
|
use crate::integration_tests::setup::{decode_packet, ChainSetup};
|
|
5
7
|
use crate::MintableClient;
|
|
6
8
|
use endpoint_v2::{MessagingFee, Origin, OutboundPacket};
|
|
@@ -13,7 +15,6 @@ use soroban_sdk::{
|
|
|
13
15
|
xdr::ToXdr,
|
|
14
16
|
Address, Bytes, BytesN, Env, IntoVal, Map, Symbol, Val, Vec,
|
|
15
17
|
};
|
|
16
|
-
|
|
17
18
|
// ============================================================================
|
|
18
19
|
// Address Conversion Utilities
|
|
19
20
|
// ============================================================================
|
|
@@ -356,16 +357,44 @@ pub fn token_balance(env: &Env, token: &Address, account: &Address) -> i128 {
|
|
|
356
357
|
// ============================================================================
|
|
357
358
|
|
|
358
359
|
pub fn set_paused(env: &Env, chain: &ChainSetup<'_>, paused: bool) {
|
|
360
|
+
// `pause` / `unpause` are protected by RBAC (`PAUSER_ROLE` / `UNPAUSER_ROLE`). Grant them to owner for tests.
|
|
361
|
+
let pauser = Symbol::new(env, PAUSER_ROLE);
|
|
362
|
+
let unpauser = Symbol::new(env, UNPAUSER_ROLE);
|
|
359
363
|
env.mock_auths(&[MockAuth {
|
|
360
364
|
address: &chain.owner,
|
|
361
365
|
invoke: &MockAuthInvoke {
|
|
362
366
|
contract: &chain.oft.address,
|
|
363
|
-
fn_name: "
|
|
364
|
-
args: (&
|
|
367
|
+
fn_name: "grant_role",
|
|
368
|
+
args: (&chain.owner, &pauser, &chain.owner).into_val(env),
|
|
365
369
|
sub_invokes: &[],
|
|
366
370
|
},
|
|
367
371
|
}]);
|
|
368
|
-
chain.oft.
|
|
372
|
+
chain.oft.grant_role(&chain.owner, &pauser, &chain.owner);
|
|
373
|
+
env.mock_auths(&[MockAuth {
|
|
374
|
+
address: &chain.owner,
|
|
375
|
+
invoke: &MockAuthInvoke {
|
|
376
|
+
contract: &chain.oft.address,
|
|
377
|
+
fn_name: "grant_role",
|
|
378
|
+
args: (&chain.owner, &unpauser, &chain.owner).into_val(env),
|
|
379
|
+
sub_invokes: &[],
|
|
380
|
+
},
|
|
381
|
+
}]);
|
|
382
|
+
chain.oft.grant_role(&chain.owner, &unpauser, &chain.owner);
|
|
383
|
+
|
|
384
|
+
env.mock_auths(&[MockAuth {
|
|
385
|
+
address: &chain.owner,
|
|
386
|
+
invoke: &MockAuthInvoke {
|
|
387
|
+
contract: &chain.oft.address,
|
|
388
|
+
fn_name: if paused { "pause" } else { "unpause" },
|
|
389
|
+
args: (&chain.owner,).into_val(env),
|
|
390
|
+
sub_invokes: &[],
|
|
391
|
+
},
|
|
392
|
+
}]);
|
|
393
|
+
if paused {
|
|
394
|
+
chain.oft.pause(&chain.owner);
|
|
395
|
+
} else {
|
|
396
|
+
chain.oft.unpause(&chain.owner);
|
|
397
|
+
}
|
|
369
398
|
}
|
|
370
399
|
|
|
371
400
|
pub fn is_paused(chain: &ChainSetup<'_>) -> bool {
|
|
@@ -377,45 +406,84 @@ pub fn is_paused(chain: &ChainSetup<'_>) -> bool {
|
|
|
377
406
|
// ============================================================================
|
|
378
407
|
|
|
379
408
|
pub fn set_fee_deposit_address(env: &Env, chain: &ChainSetup<'_>, deposit_address: &Address) {
|
|
409
|
+
// `set_fee_deposit_address` is protected by RBAC (`FEE_ADMIN_ROLE`). Grant it to owner for tests.
|
|
410
|
+
let role = Symbol::new(env, FEE_ADMIN_ROLE);
|
|
411
|
+
env.mock_auths(&[MockAuth {
|
|
412
|
+
address: &chain.owner,
|
|
413
|
+
invoke: &MockAuthInvoke {
|
|
414
|
+
contract: &chain.oft.address,
|
|
415
|
+
fn_name: "grant_role",
|
|
416
|
+
args: (&chain.owner, &role, &chain.owner).into_val(env),
|
|
417
|
+
sub_invokes: &[],
|
|
418
|
+
},
|
|
419
|
+
}]);
|
|
420
|
+
chain.oft.grant_role(&chain.owner, &role, &chain.owner);
|
|
421
|
+
|
|
380
422
|
let deposit_address_opt = Some(deposit_address.clone());
|
|
381
423
|
env.mock_auths(&[MockAuth {
|
|
382
424
|
address: &chain.owner,
|
|
383
425
|
invoke: &MockAuthInvoke {
|
|
384
426
|
contract: &chain.oft.address,
|
|
385
427
|
fn_name: "set_fee_deposit_address",
|
|
386
|
-
args: (&deposit_address_opt,).into_val(env),
|
|
428
|
+
args: (&deposit_address_opt, &chain.owner).into_val(env),
|
|
387
429
|
sub_invokes: &[],
|
|
388
430
|
},
|
|
389
431
|
}]);
|
|
390
|
-
chain.oft.set_fee_deposit_address(&deposit_address_opt);
|
|
432
|
+
chain.oft.set_fee_deposit_address(&deposit_address_opt, &chain.owner);
|
|
391
433
|
}
|
|
392
434
|
|
|
393
435
|
pub fn set_default_fee_bps(env: &Env, chain: &ChainSetup<'_>, fee_bps: u32) {
|
|
436
|
+
// `set_default_fee_bps` is protected by RBAC (`FEE_ADMIN_ROLE`). Grant it to owner for tests.
|
|
437
|
+
let role = Symbol::new(env, FEE_ADMIN_ROLE);
|
|
438
|
+
env.mock_auths(&[MockAuth {
|
|
439
|
+
address: &chain.owner,
|
|
440
|
+
invoke: &MockAuthInvoke {
|
|
441
|
+
contract: &chain.oft.address,
|
|
442
|
+
fn_name: "grant_role",
|
|
443
|
+
args: (&chain.owner, &role, &chain.owner).into_val(env),
|
|
444
|
+
sub_invokes: &[],
|
|
445
|
+
},
|
|
446
|
+
}]);
|
|
447
|
+
chain.oft.grant_role(&chain.owner, &role, &chain.owner);
|
|
448
|
+
|
|
394
449
|
let fee_bps_opt = Some(fee_bps);
|
|
395
450
|
env.mock_auths(&[MockAuth {
|
|
396
451
|
address: &chain.owner,
|
|
397
452
|
invoke: &MockAuthInvoke {
|
|
398
453
|
contract: &chain.oft.address,
|
|
399
454
|
fn_name: "set_default_fee_bps",
|
|
400
|
-
args: (&fee_bps_opt,).into_val(env),
|
|
455
|
+
args: (&fee_bps_opt, &chain.owner).into_val(env),
|
|
401
456
|
sub_invokes: &[],
|
|
402
457
|
},
|
|
403
458
|
}]);
|
|
404
|
-
chain.oft.set_default_fee_bps(&fee_bps_opt);
|
|
459
|
+
chain.oft.set_default_fee_bps(&fee_bps_opt, &chain.owner);
|
|
405
460
|
}
|
|
406
461
|
|
|
407
462
|
pub fn set_fee_bps(env: &Env, chain: &ChainSetup<'_>, dst_eid: u32, fee_bps: u32) {
|
|
463
|
+
// `set_fee_bps` is protected by RBAC (`FEE_ADMIN_ROLE`). Grant it to owner for tests.
|
|
464
|
+
let role = Symbol::new(env, FEE_ADMIN_ROLE);
|
|
465
|
+
env.mock_auths(&[MockAuth {
|
|
466
|
+
address: &chain.owner,
|
|
467
|
+
invoke: &MockAuthInvoke {
|
|
468
|
+
contract: &chain.oft.address,
|
|
469
|
+
fn_name: "grant_role",
|
|
470
|
+
args: (&chain.owner, &role, &chain.owner).into_val(env),
|
|
471
|
+
sub_invokes: &[],
|
|
472
|
+
},
|
|
473
|
+
}]);
|
|
474
|
+
chain.oft.grant_role(&chain.owner, &role, &chain.owner);
|
|
475
|
+
|
|
408
476
|
let fee_bps_opt = Some(fee_bps);
|
|
409
477
|
env.mock_auths(&[MockAuth {
|
|
410
478
|
address: &chain.owner,
|
|
411
479
|
invoke: &MockAuthInvoke {
|
|
412
480
|
contract: &chain.oft.address,
|
|
413
481
|
fn_name: "set_fee_bps",
|
|
414
|
-
args: (&dst_eid, &fee_bps_opt).into_val(env),
|
|
482
|
+
args: (&dst_eid, &fee_bps_opt, &chain.owner).into_val(env),
|
|
415
483
|
sub_invokes: &[],
|
|
416
484
|
},
|
|
417
485
|
}]);
|
|
418
|
-
chain.oft.set_fee_bps(&dst_eid, &fee_bps_opt);
|
|
486
|
+
chain.oft.set_fee_bps(&dst_eid, &fee_bps_opt, &chain.owner);
|
|
419
487
|
}
|
|
420
488
|
|
|
421
489
|
// ============================================================================
|
|
@@ -442,17 +510,30 @@ pub fn set_rate_limit_with_mode(
|
|
|
442
510
|
window_seconds: u64,
|
|
443
511
|
mode: Mode,
|
|
444
512
|
) {
|
|
513
|
+
// `set_rate_limit` is protected by RBAC (`RATE_LIMITER_ADMIN_ROLE`). Grant it to owner for tests.
|
|
514
|
+
let role = Symbol::new(env, RATE_LIMITER_ADMIN_ROLE);
|
|
515
|
+
env.mock_auths(&[MockAuth {
|
|
516
|
+
address: &chain.owner,
|
|
517
|
+
invoke: &MockAuthInvoke {
|
|
518
|
+
contract: &chain.oft.address,
|
|
519
|
+
fn_name: "grant_role",
|
|
520
|
+
args: (&chain.owner, &role, &chain.owner).into_val(env),
|
|
521
|
+
sub_invokes: &[],
|
|
522
|
+
},
|
|
523
|
+
}]);
|
|
524
|
+
chain.oft.grant_role(&chain.owner, &role, &chain.owner);
|
|
525
|
+
|
|
445
526
|
let config = Some(RateLimitConfig { limit, window_seconds, mode });
|
|
446
527
|
env.mock_auths(&[MockAuth {
|
|
447
528
|
address: &chain.owner,
|
|
448
529
|
invoke: &MockAuthInvoke {
|
|
449
530
|
contract: &chain.oft.address,
|
|
450
531
|
fn_name: "set_rate_limit",
|
|
451
|
-
args: (direction, &dst_eid, &config).into_val(env),
|
|
532
|
+
args: (direction, &dst_eid, &config, &chain.owner).into_val(env),
|
|
452
533
|
sub_invokes: &[],
|
|
453
534
|
},
|
|
454
535
|
}]);
|
|
455
|
-
chain.oft.set_rate_limit(direction, &dst_eid, &config);
|
|
536
|
+
chain.oft.set_rate_limit(direction, &dst_eid, &config, &chain.owner);
|
|
456
537
|
}
|
|
457
538
|
|
|
458
539
|
pub fn rate_limit_capacity(chain: &ChainSetup<'_>, direction: &Direction, eid: u32) -> i128 {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
use common_macros::{contract_error, contract_trait,
|
|
1
|
+
use common_macros::{contract_error, contract_trait, only_role, storage};
|
|
2
2
|
use soroban_sdk::{assert_with_error, contractevent, token::TokenClient, Address, Env};
|
|
3
|
-
use utils::{
|
|
3
|
+
use utils::{option_ext::OptionExt, rbac::RoleBasedAccessControl};
|
|
4
|
+
|
|
5
|
+
/// Role for fee configuration (set_default_fee_bps, set_fee_bps, set_fee_deposit_address).
|
|
6
|
+
pub const FEE_ADMIN_ROLE: &str = "FEE_ADMIN_ROLE";
|
|
4
7
|
|
|
5
8
|
/// Base fee in basis points (10,000 BPS = 100%)
|
|
6
9
|
/// Used as denominator in fee calculations
|
|
@@ -69,7 +72,7 @@ pub struct FeeDepositAddressSet {
|
|
|
69
72
|
// =========================================================================
|
|
70
73
|
|
|
71
74
|
#[contract_trait]
|
|
72
|
-
pub trait OFTFee: OFTFeeInternal +
|
|
75
|
+
pub trait OFTFee: OFTFeeInternal + RoleBasedAccessControl {
|
|
73
76
|
// =========================================================================
|
|
74
77
|
// Management Functions
|
|
75
78
|
// =========================================================================
|
|
@@ -79,8 +82,9 @@ pub trait OFTFee: OFTFeeInternal + Auth {
|
|
|
79
82
|
/// - `Some(n)`: sets the default fee to `n` basis points (must be >0 and <=10,000).
|
|
80
83
|
/// - `Some(0)`: rejected — use `None` to remove the default fee instead.
|
|
81
84
|
/// - `None`: removes the default fee (effective rate becomes 0).
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
/// * `operator` - The address that must have FEE_ADMIN_ROLE
|
|
86
|
+
#[only_role(operator, FEE_ADMIN_ROLE)]
|
|
87
|
+
fn set_default_fee_bps(env: &soroban_sdk::Env, default_fee_bps: &Option<u32>, operator: &soroban_sdk::Address) {
|
|
84
88
|
Self::__set_default_fee_bps(env, default_fee_bps);
|
|
85
89
|
}
|
|
86
90
|
|
|
@@ -92,14 +96,23 @@ pub trait OFTFee: OFTFeeInternal + Auth {
|
|
|
92
96
|
/// # Arguments
|
|
93
97
|
/// * `dst_eid` - The destination endpoint ID
|
|
94
98
|
/// * `fee_bps` - The fee rate (0-10,000), or None to remove the fee configuration
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
/// * `operator` - The address that must have FEE_ADMIN_ROLE
|
|
100
|
+
#[only_role(operator, FEE_ADMIN_ROLE)]
|
|
101
|
+
fn set_fee_bps(env: &soroban_sdk::Env, dst_eid: u32, fee_bps: &Option<u32>, operator: &soroban_sdk::Address) {
|
|
97
102
|
Self::__set_fee_bps(env, dst_eid, fee_bps);
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
/// Sets or removes the address where collected fees will be deposited.
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
///
|
|
107
|
+
/// # Arguments
|
|
108
|
+
/// * `fee_deposit_address` - The address to deposit fees to, or None to remove the fee deposit address
|
|
109
|
+
/// * `operator` - The address that must have FEE_ADMIN_ROLE
|
|
110
|
+
#[only_role(operator, FEE_ADMIN_ROLE)]
|
|
111
|
+
fn set_fee_deposit_address(
|
|
112
|
+
env: &soroban_sdk::Env,
|
|
113
|
+
fee_deposit_address: &Option<soroban_sdk::Address>,
|
|
114
|
+
operator: &soroban_sdk::Address,
|
|
115
|
+
) {
|
|
103
116
|
Self::__set_fee_deposit_address(env, fee_deposit_address);
|
|
104
117
|
}
|
|
105
118
|
|
|
@@ -134,7 +147,7 @@ pub trait OFTFee: OFTFeeInternal + Auth {
|
|
|
134
147
|
}
|
|
135
148
|
|
|
136
149
|
/// Internal trait for OFT fee operations used by OFT hooks.
|
|
137
|
-
/// Contains only truly internal methods that are called from
|
|
150
|
+
/// Contains only truly internal methods that are called from OFTFee implementations.
|
|
138
151
|
pub trait OFTFeeInternal {
|
|
139
152
|
// =========================================================================
|
|
140
153
|
// OFT Hooks
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
use common_macros::{contract_error, contract_trait,
|
|
1
|
+
use common_macros::{contract_error, contract_trait, only_role, storage};
|
|
2
2
|
use soroban_sdk::{assert_with_error, contractevent, Env};
|
|
3
|
-
use utils::
|
|
3
|
+
use utils::rbac::RoleBasedAccessControl;
|
|
4
|
+
|
|
5
|
+
/// Role for pausing the contract.
|
|
6
|
+
pub const PAUSER_ROLE: &str = "PAUSER_ROLE";
|
|
7
|
+
|
|
8
|
+
/// Role for unpausing the contract.
|
|
9
|
+
pub const UNPAUSER_ROLE: &str = "UNPAUSER_ROLE";
|
|
4
10
|
|
|
5
11
|
// =========================================================================
|
|
6
12
|
// Storage
|
|
@@ -37,18 +43,33 @@ pub struct PausedSet {
|
|
|
37
43
|
// =========================================================================
|
|
38
44
|
|
|
39
45
|
#[contract_trait]
|
|
40
|
-
pub trait OFTPausable: OFTPausableInternal +
|
|
41
|
-
|
|
46
|
+
pub trait OFTPausable: OFTPausableInternal + RoleBasedAccessControl {
|
|
47
|
+
// =========================================================================
|
|
48
|
+
// Management Functions
|
|
49
|
+
// =========================================================================
|
|
50
|
+
|
|
51
|
+
/// Pauses the OFT. When paused, the OFT will reject new send/receive/quote_send/quote_oft operations.
|
|
42
52
|
///
|
|
43
|
-
///
|
|
53
|
+
/// # Arguments
|
|
54
|
+
/// * `operator` - The address that must have PAUSER_ROLE
|
|
55
|
+
#[only_role(operator, PAUSER_ROLE)]
|
|
56
|
+
fn pause(env: &soroban_sdk::Env, operator: &soroban_sdk::Address) {
|
|
57
|
+
Self::__set_paused(env, true);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// Unpauses the OFT.
|
|
44
61
|
///
|
|
45
62
|
/// # Arguments
|
|
46
|
-
/// * `
|
|
47
|
-
#[
|
|
48
|
-
fn
|
|
49
|
-
Self::__set_paused(env,
|
|
63
|
+
/// * `operator` - The address that must have UNPAUSER_ROLE
|
|
64
|
+
#[only_role(operator, UNPAUSER_ROLE)]
|
|
65
|
+
fn unpause(env: &soroban_sdk::Env, operator: &soroban_sdk::Address) {
|
|
66
|
+
Self::__set_paused(env, false);
|
|
50
67
|
}
|
|
51
68
|
|
|
69
|
+
// =========================================================================
|
|
70
|
+
// View Functions
|
|
71
|
+
// =========================================================================
|
|
72
|
+
|
|
52
73
|
/// Returns the paused state of the OFT.
|
|
53
74
|
fn is_paused(env: &soroban_sdk::Env) -> bool {
|
|
54
75
|
Self::__is_paused(env)
|
|
@@ -56,7 +77,7 @@ pub trait OFTPausable: OFTPausableInternal + Auth {
|
|
|
56
77
|
}
|
|
57
78
|
|
|
58
79
|
/// Internal trait for pausable operations used by OFT hooks.
|
|
59
|
-
/// Contains only truly internal methods that are called from
|
|
80
|
+
/// Contains only truly internal methods that are called from OFTPausable implementations.
|
|
60
81
|
pub trait OFTPausableInternal {
|
|
61
82
|
// =========================================================================
|
|
62
83
|
// OFT Hooks
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
use crate as oft;
|
|
2
|
-
use common_macros::{contract_error, contract_trait,
|
|
2
|
+
use common_macros::{contract_error, contract_trait, only_role, storage};
|
|
3
3
|
use soroban_sdk::{assert_with_error, contractevent, contracttype, Env};
|
|
4
|
-
use utils::
|
|
4
|
+
use utils::rbac::RoleBasedAccessControl;
|
|
5
|
+
|
|
6
|
+
/// Role for rate limiter configuration (set_rate_limit).
|
|
7
|
+
pub const RATE_LIMITER_ADMIN_ROLE: &str = "RATE_LIMITER_ADMIN_ROLE";
|
|
5
8
|
|
|
6
9
|
// =========================================================================
|
|
7
10
|
// Types
|
|
@@ -94,7 +97,7 @@ pub struct RateLimitSet {
|
|
|
94
97
|
// =========================================================================
|
|
95
98
|
|
|
96
99
|
#[contract_trait]
|
|
97
|
-
pub trait RateLimiter: RateLimiterInternal +
|
|
100
|
+
pub trait RateLimiter: RateLimiterInternal + RoleBasedAccessControl {
|
|
98
101
|
// =========================================================================
|
|
99
102
|
// Management Functions
|
|
100
103
|
// =========================================================================
|
|
@@ -105,12 +108,14 @@ pub trait RateLimiter: RateLimiterInternal + Auth {
|
|
|
105
108
|
/// * `direction` - The direction (Inbound or Outbound)
|
|
106
109
|
/// * `eid` - The endpoint ID
|
|
107
110
|
/// * `config` - The rate limit configuration, or None to remove the rate limit
|
|
108
|
-
|
|
111
|
+
/// * `operator` - The address that must have RATE_LIMITER_ADMIN_ROLE
|
|
112
|
+
#[only_role(operator, RATE_LIMITER_ADMIN_ROLE)]
|
|
109
113
|
fn set_rate_limit(
|
|
110
114
|
env: &soroban_sdk::Env,
|
|
111
115
|
direction: &oft::rate_limiter::Direction,
|
|
112
116
|
eid: u32,
|
|
113
117
|
config: &Option<oft::rate_limiter::RateLimitConfig>,
|
|
118
|
+
operator: &soroban_sdk::Address,
|
|
114
119
|
) {
|
|
115
120
|
Self::__set_rate_limit(env, direction, eid, config);
|
|
116
121
|
}
|
|
@@ -7,7 +7,7 @@ use crate::{
|
|
|
7
7
|
},
|
|
8
8
|
oft_types::{lock_unlock, mint_burn, OftType},
|
|
9
9
|
};
|
|
10
|
-
use common_macros::{contract_impl, storage};
|
|
10
|
+
use common_macros::{contract_impl, lz_contract, storage};
|
|
11
11
|
use oapp_macros::oapp;
|
|
12
12
|
use oft_core::{
|
|
13
13
|
impl_oft_lz_receive, utils as oft_utils, OFTCore, OFTError, OFTFeeDetail, OFTInternal, OFTLimit, OFTReceipt,
|
|
@@ -29,6 +29,7 @@ enum OFTStorage {
|
|
|
29
29
|
// OFT Contract
|
|
30
30
|
// =========================================================================
|
|
31
31
|
|
|
32
|
+
#[lz_contract]
|
|
32
33
|
#[oapp]
|
|
33
34
|
pub struct OFT;
|
|
34
35
|
|
|
@@ -42,11 +43,10 @@ impl OFT {
|
|
|
42
43
|
token: &Address,
|
|
43
44
|
shared_decimals: u32,
|
|
44
45
|
oft_type: OftType,
|
|
45
|
-
owner: &Address,
|
|
46
46
|
endpoint: &Address,
|
|
47
47
|
delegate: &Address,
|
|
48
48
|
) {
|
|
49
|
-
Self::__initialize_oft(env, token, shared_decimals,
|
|
49
|
+
Self::__initialize_oft(env, token, shared_decimals, delegate, endpoint, delegate);
|
|
50
50
|
OFTStorage::set_oft_type(env, &oft_type);
|
|
51
51
|
}
|
|
52
52
|
|