@layerzerolabs/protocol-stellar-v2 0.2.35 → 0.2.37
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 +274 -268
- package/.turbo/turbo-lint.log +216 -213
- package/.turbo/turbo-test.log +1735 -1994
- package/contracts/common-macros/src/auth.rs +5 -5
- package/contracts/common-macros/src/lib.rs +69 -0
- package/contracts/common-macros/src/rbac.rs +90 -0
- package/contracts/common-macros/src/tests/lz_contract.rs +5 -7
- package/contracts/common-macros/src/tests/mod.rs +1 -0
- package/contracts/common-macros/src/tests/rbac.rs +420 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +4 -4
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +5 -12
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__rbac__snapshot_preserve_function_signature.snap +17 -0
- package/contracts/common-macros/src/tests/storage/parse_name.rs +0 -1
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_default.rs +1 -1
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig.rs +1 -1
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig_upgradeable.rs +1 -1
- package/contracts/macro-integration-tests/tests/runtime/multisig/self_auth.rs +1 -1
- package/contracts/macro-integration-tests/tests/runtime/ownable/initialization.rs +8 -5
- package/contracts/macro-integration-tests/tests/runtime/ownable/ownership_transfer.rs +2 -2
- package/contracts/macro-integration-tests/tests/runtime/rbac/guard_behavior.rs +91 -0
- package/contracts/macro-integration-tests/tests/runtime/rbac/mod.rs +30 -0
- package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +2 -2
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +4 -4
- package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/basic.rs +1 -1
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/basic.rs +1 -1
- package/contracts/macro-integration-tests/tests/ui/rbac/fail/missing_env.rs +18 -0
- package/contracts/macro-integration-tests/tests/ui/rbac/fail/missing_env.stderr +16 -0
- package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_address.rs +18 -0
- package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_address.stderr +24 -0
- package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_found.rs +18 -0
- package/contracts/macro-integration-tests/tests/ui/rbac/fail/param_not_found.stderr +24 -0
- package/contracts/macro-integration-tests/tests/ui/rbac/pass/basic.rs +71 -0
- package/contracts/macro-integration-tests/tests/ui_rbac.rs +12 -0
- package/contracts/oapps/oft/src/interfaces/mintable.rs +2 -2
- package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +2 -2
- package/contracts/oapps/oft/src/tests/extensions/pausable.rs +2 -2
- package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +2 -2
- package/contracts/oapps/sac-manager/Cargo.toml +0 -1
- package/contracts/oapps/sac-manager/src/interfaces/mod.rs +3 -0
- package/contracts/oapps/sac-manager/src/interfaces/sac_admin_wrapper.rs +49 -0
- package/contracts/oapps/sac-manager/src/lib.rs +3 -3
- package/contracts/oapps/sac-manager/src/sac_manager.rs +45 -73
- package/contracts/oapps/sac-manager/src/storage.rs +2 -9
- package/contracts/oapps/sac-manager/src/tests/sac_manager/clawback.rs +8 -10
- package/contracts/oapps/sac-manager/src/tests/sac_manager/mint.rs +13 -18
- package/contracts/oapps/sac-manager/src/tests/sac_manager/mod.rs +0 -1
- package/contracts/oapps/sac-manager/src/tests/sac_manager/set_admin.rs +22 -12
- package/contracts/oapps/sac-manager/src/tests/sac_manager/set_authorized.rs +19 -9
- package/contracts/oapps/sac-manager/src/tests/sac_manager/test_helper.rs +27 -10
- package/contracts/oapps/sac-manager/src/tests/sac_manager/view_functions.rs +0 -15
- package/contracts/oapps/sac-manager/src/tests/test_helper.rs +19 -28
- package/contracts/upgrader/src/lib.rs +5 -2
- package/contracts/utils/src/auth.rs +6 -2
- package/contracts/utils/src/errors.rs +18 -0
- package/contracts/utils/src/lib.rs +1 -0
- package/contracts/utils/src/multisig.rs +5 -1
- package/contracts/utils/src/ownable.rs +1 -1
- package/contracts/utils/src/rbac.rs +428 -0
- package/contracts/utils/src/tests/auth.rs +2 -2
- package/contracts/utils/src/tests/mod.rs +1 -0
- package/contracts/utils/src/tests/multisig.rs +2 -2
- package/contracts/utils/src/tests/ownable.rs +4 -5
- package/contracts/utils/src/tests/rbac.rs +559 -0
- package/contracts/utils/src/tests/ttl_configurable.rs +5 -6
- package/contracts/utils/src/tests/upgradeable.rs +4 -5
- package/contracts/workers/worker/src/worker.rs +1 -1
- package/package.json +3 -3
- package/sdk/.turbo/turbo-test.log +368 -366
- package/sdk/dist/generated/bml.d.ts +53 -3
- package/sdk/dist/generated/bml.js +27 -3
- package/sdk/dist/generated/counter.d.ts +55 -5
- package/sdk/dist/generated/counter.js +28 -4
- package/sdk/dist/generated/dvn.d.ts +55 -5
- package/sdk/dist/generated/dvn.js +28 -4
- package/sdk/dist/generated/dvn_fee_lib.d.ts +55 -5
- package/sdk/dist/generated/dvn_fee_lib.js +28 -4
- package/sdk/dist/generated/endpoint.d.ts +55 -5
- package/sdk/dist/generated/endpoint.js +28 -4
- package/sdk/dist/generated/executor.d.ts +55 -5
- package/sdk/dist/generated/executor.js +28 -4
- package/sdk/dist/generated/executor_fee_lib.d.ts +55 -5
- package/sdk/dist/generated/executor_fee_lib.js +28 -4
- package/sdk/dist/generated/executor_helper.d.ts +53 -3
- package/sdk/dist/generated/executor_helper.js +27 -3
- package/sdk/dist/generated/layerzero_view.d.ts +55 -5
- package/sdk/dist/generated/layerzero_view.js +28 -4
- package/sdk/dist/generated/oft.d.ts +55 -5
- package/sdk/dist/generated/oft.js +28 -4
- package/sdk/dist/generated/price_feed.d.ts +55 -5
- package/sdk/dist/generated/price_feed.js +28 -4
- package/sdk/dist/generated/sac_manager.d.ts +213 -687
- package/sdk/dist/generated/sac_manager.js +57 -239
- package/sdk/dist/generated/sml.d.ts +55 -5
- package/sdk/dist/generated/sml.js +28 -4
- package/sdk/dist/generated/treasury.d.ts +55 -5
- package/sdk/dist/generated/treasury.js +28 -4
- package/sdk/dist/generated/uln302.d.ts +55 -5
- package/sdk/dist/generated/uln302.js +28 -4
- package/sdk/dist/generated/upgrader.d.ts +53 -3
- package/sdk/dist/generated/upgrader.js +27 -3
- package/sdk/package.json +1 -1
- package/sdk/test/oft-sml.test.ts +10 -9
- package/sdk/test/{sac-manager-redistribution.test.ts → sac-manager.test.ts} +49 -25
- package/contracts/oapps/sac-manager/src/errors.rs +0 -14
- package/contracts/oapps/sac-manager/src/tests/sac_manager/set_minter.rs +0 -69
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//! SAC Admin Wrapper trait definition.
|
|
2
|
+
//!
|
|
3
|
+
//! Defines the admin operations that can be performed on a Stellar Asset Contract (SAC).
|
|
4
|
+
|
|
5
|
+
use common_macros::contract_trait;
|
|
6
|
+
use soroban_sdk::{Address, Env};
|
|
7
|
+
|
|
8
|
+
#[contract_trait]
|
|
9
|
+
pub trait SACAdminWrapper {
|
|
10
|
+
/// Sets the administrator to the specified address `new_admin`.
|
|
11
|
+
///
|
|
12
|
+
/// # Arguments
|
|
13
|
+
///
|
|
14
|
+
/// * `env` - The Soroban environment.
|
|
15
|
+
/// * `new_admin` - The address which will be the administrator of the token contract.
|
|
16
|
+
/// * `operator` - The address authorizing the invocation.
|
|
17
|
+
fn set_admin(env: &Env, new_admin: &Address, operator: &Address);
|
|
18
|
+
|
|
19
|
+
/// Sets whether the account is authorized to use its balance.
|
|
20
|
+
/// If `authorize` is true, `id` can use its balance; otherwise it is blacklisted.
|
|
21
|
+
///
|
|
22
|
+
/// # Arguments
|
|
23
|
+
///
|
|
24
|
+
/// * `env` - The Soroban environment.
|
|
25
|
+
/// * `id` - The address being (de-)authorized.
|
|
26
|
+
/// * `authorize` - Whether `id` can use its balance.
|
|
27
|
+
/// * `operator` - The address authorizing the invocation.
|
|
28
|
+
fn set_authorized(env: &Env, id: &Address, authorize: bool, operator: &Address);
|
|
29
|
+
|
|
30
|
+
/// Clawback `amount` from `from` account. The amount is burned in the clawback process.
|
|
31
|
+
///
|
|
32
|
+
/// # Arguments
|
|
33
|
+
///
|
|
34
|
+
/// * `env` - The Soroban environment.
|
|
35
|
+
/// * `from` - The address holding the balance to claw back from.
|
|
36
|
+
/// * `amount` - The amount of tokens to claw back.
|
|
37
|
+
/// * `operator` - The address authorizing the invocation.
|
|
38
|
+
fn clawback(env: &Env, from: &Address, amount: i128, operator: &Address);
|
|
39
|
+
|
|
40
|
+
/// Mints `amount` to `to`.
|
|
41
|
+
///
|
|
42
|
+
/// # Arguments
|
|
43
|
+
///
|
|
44
|
+
/// * `env` - The Soroban environment.
|
|
45
|
+
/// * `to` - The address which will receive the minted tokens.
|
|
46
|
+
/// * `amount` - The amount of tokens to be minted.
|
|
47
|
+
/// * `operator` - The address authorizing the invocation.
|
|
48
|
+
fn mint(env: &Env, to: &Address, amount: i128, operator: &Address);
|
|
49
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#![no_std]
|
|
2
2
|
|
|
3
|
-
mod
|
|
3
|
+
mod interfaces;
|
|
4
4
|
|
|
5
|
-
pub use
|
|
5
|
+
pub use interfaces::{SACAdminWrapper, SACAdminWrapperClient};
|
|
6
6
|
|
|
7
7
|
cfg_if::cfg_if! {
|
|
8
8
|
// Include implementation when NOT in library mode, OR when testutils is enabled (for tests)
|
|
@@ -11,7 +11,7 @@ cfg_if::cfg_if! {
|
|
|
11
11
|
mod sac_manager;
|
|
12
12
|
|
|
13
13
|
// Export the contract and client for testing purposes
|
|
14
|
-
pub use sac_manager::{
|
|
14
|
+
pub use sac_manager::{SACManager, SACManagerClient};
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -2,19 +2,30 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! This contract becomes the admin of a SAC and provides:
|
|
4
4
|
//! - Mintable interface for OFT (mint on credit only; OFT burns on the token directly)
|
|
5
|
-
//! -
|
|
6
|
-
//! - Upgradeable (owner-authorized)
|
|
5
|
+
//! - Role-based access control operations (clawback, set_admin, set_authorized)
|
|
7
6
|
//!
|
|
8
7
|
//! ## Authorization Model
|
|
9
8
|
//!
|
|
10
|
-
//! - **Owner** (via Ownable): The admin address. Can
|
|
11
|
-
//! - **
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
use
|
|
9
|
+
//! - **Owner** (via Ownable): The deployer/admin address. Can manage TTL and grant/revoke roles.
|
|
10
|
+
//! - **RBAC roles**: Access is enforced by role.
|
|
11
|
+
//! - `ADMIN_MANAGER_ROLE`: set_admin
|
|
12
|
+
//! - `MINTER_ROLE`: mint (e.g. for OFT credit)
|
|
13
|
+
//! - `BLACKLISTER_ROLE`: set_authorized
|
|
14
|
+
//! - `CLAWBACK_ROLE`: clawback
|
|
15
|
+
|
|
16
|
+
use crate::{interfaces::SACAdminWrapper, storage::SACManagerStorage};
|
|
17
|
+
use common_macros::{contract_impl, lz_contract, only_role};
|
|
18
|
+
use soroban_sdk::{token::StellarAssetClient, Address, Env};
|
|
19
|
+
use utils::rbac::RoleBasedAccessControl;
|
|
20
|
+
|
|
21
|
+
/// Role that can set the admin
|
|
22
|
+
const ADMIN_MANAGER_ROLE: &str = "ADMIN_MGR";
|
|
23
|
+
/// Role that can mint tokens
|
|
24
|
+
const MINTER_ROLE: &str = "MINTER";
|
|
25
|
+
/// Role that can blacklist users
|
|
26
|
+
const BLACKLISTER_ROLE: &str = "BLKLISTR";
|
|
27
|
+
/// Role that can clawback tokens from users
|
|
28
|
+
const CLAWBACK_ROLE: &str = "CLAWBACK";
|
|
18
29
|
|
|
19
30
|
// =========================================================================
|
|
20
31
|
// SAC Manager Contract
|
|
@@ -24,92 +35,53 @@ use utils::ownable::OwnableInitializer;
|
|
|
24
35
|
///
|
|
25
36
|
/// Manages a SAC as its admin, forwarding token actions to
|
|
26
37
|
/// the underlying SAC while enforcing access control.
|
|
27
|
-
#[lz_contract
|
|
28
|
-
pub struct
|
|
38
|
+
#[lz_contract]
|
|
39
|
+
pub struct SACManager;
|
|
29
40
|
|
|
30
41
|
#[contract_impl]
|
|
31
|
-
impl
|
|
42
|
+
impl SACManager {
|
|
32
43
|
/// Constructs the SAC manager contract.
|
|
33
44
|
///
|
|
34
45
|
/// # Arguments
|
|
35
46
|
/// * `sac_token` - The underlying Stellar Asset Contract address
|
|
36
|
-
/// * `owner` - The initial owner address (for
|
|
37
|
-
///
|
|
38
|
-
/// Minters can be set separately via `set_minter` after construction.
|
|
47
|
+
/// * `owner` - The initial owner address (for TTL management, role grants)
|
|
39
48
|
pub fn __constructor(env: &Env, sac_token: &Address, owner: &Address) {
|
|
40
49
|
Self::init_owner(env, owner);
|
|
41
|
-
|
|
50
|
+
SACManagerStorage::set_sac_token(env, sac_token);
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/// Delegates to the underlying SAC to clawback `amount` from `from` account.
|
|
49
|
-
#[only_auth]
|
|
50
|
-
pub fn clawback(env: &Env, from: &Address, amount: i128) {
|
|
51
|
-
sac_client(env).clawback(from, &amount);
|
|
53
|
+
/// Returns the underlying SAC (Stellar Asset Contract) address.
|
|
54
|
+
pub fn underlying_sac(env: &Env) -> Address {
|
|
55
|
+
SACManagerStorage::sac_token(env).unwrap()
|
|
52
56
|
}
|
|
57
|
+
}
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
#[contract_impl(contracttrait)]
|
|
60
|
+
impl SACAdminWrapper for SACManager {
|
|
61
|
+
#[only_role(operator, ADMIN_MANAGER_ROLE)]
|
|
62
|
+
fn set_admin(env: &Env, new_admin: &Address, operator: &Address) {
|
|
63
|
+
sac_client(env).set_admin(new_admin);
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
pub fn set_authorized(env: &Env, id: &Address, authorize: bool) {
|
|
66
|
+
#[only_role(operator, BLACKLISTER_ROLE)]
|
|
67
|
+
fn set_authorized(env: &Env, id: &Address, authorize: bool, operator: &Address) {
|
|
63
68
|
sac_client(env).set_authorized(id, &authorize);
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
let mut minters = SacManagerStorage::minters(env);
|
|
70
|
-
let minter_index = minters.first_index_of(minter);
|
|
71
|
-
if active {
|
|
72
|
-
assert_with_error!(env, minter_index.is_none(), SacManagerError::AlreadyMinter);
|
|
73
|
-
minters.push_back(minter.clone());
|
|
74
|
-
} else {
|
|
75
|
-
minters.remove(minter_index.unwrap_or_panic(env, SacManagerError::MinterNotFound));
|
|
76
|
-
}
|
|
77
|
-
SacManagerStorage::set_minters(env, &minters);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// =========================================================================
|
|
81
|
-
// View Functions
|
|
82
|
-
// =========================================================================
|
|
83
|
-
|
|
84
|
-
/// Returns the underlying SAC (Stellar Asset Contract) address.
|
|
85
|
-
pub fn underlying_sac(env: &Env) -> Address {
|
|
86
|
-
SacManagerStorage::sac_token(env).unwrap()
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/// Returns the list of addresses authorized to call mint.
|
|
90
|
-
pub fn minters(env: &Env) -> Vec<Address> {
|
|
91
|
-
SacManagerStorage::minters(env)
|
|
71
|
+
#[only_role(operator, CLAWBACK_ROLE)]
|
|
72
|
+
fn clawback(env: &Env, from: &Address, amount: i128, operator: &Address) {
|
|
73
|
+
sac_client(env).clawback(from, &amount);
|
|
92
74
|
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// =========================================================================
|
|
96
|
-
// Mintable Implementation (OFT mint on credit)
|
|
97
|
-
// =========================================================================
|
|
98
|
-
|
|
99
|
-
#[contract_impl]
|
|
100
|
-
impl Mintable for SacManager {
|
|
101
|
-
fn mint(env: &Env, to: &Address, amount: i128, operation: &Address) {
|
|
102
|
-
assert_with_error!(env, Self::minters(env).contains(operation), SacManagerError::Unauthorized);
|
|
103
|
-
operation.require_auth();
|
|
104
75
|
|
|
76
|
+
#[only_role(operator, MINTER_ROLE)]
|
|
77
|
+
fn mint(env: &Env, to: &Address, amount: i128, operator: &Address) {
|
|
105
78
|
sac_client(env).mint(to, &amount);
|
|
106
79
|
}
|
|
107
80
|
}
|
|
108
81
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// =========================================================================
|
|
82
|
+
#[contract_impl(contracttrait)]
|
|
83
|
+
impl RoleBasedAccessControl for SACManager {}
|
|
112
84
|
|
|
113
85
|
fn sac_client(env: &Env) -> StellarAssetClient<'_> {
|
|
114
|
-
StellarAssetClient::new(env, &
|
|
86
|
+
StellarAssetClient::new(env, &SACManager::underlying_sac(env))
|
|
115
87
|
}
|
|
@@ -3,18 +3,11 @@
|
|
|
3
3
|
//! This file contains the core storage.
|
|
4
4
|
|
|
5
5
|
use common_macros::storage;
|
|
6
|
-
use soroban_sdk::
|
|
6
|
+
use soroban_sdk::Address;
|
|
7
7
|
|
|
8
|
-
/// Core storage for the SacManager contract.
|
|
9
|
-
/// Contains essential state.
|
|
10
8
|
#[storage]
|
|
11
|
-
pub enum
|
|
9
|
+
pub enum SACManagerStorage {
|
|
12
10
|
/// The underlying SAC (Stellar Asset Contract) address
|
|
13
11
|
#[instance(Address)]
|
|
14
12
|
SacToken,
|
|
15
|
-
|
|
16
|
-
/// Addresses authorized to call mint (e.g. OFT or other minters).
|
|
17
|
-
#[persistent(Vec<Address>)]
|
|
18
|
-
#[default(Vec::new(env))]
|
|
19
|
-
Minters,
|
|
20
13
|
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
//! Clawback Integration Tests
|
|
2
2
|
//!
|
|
3
|
-
//!
|
|
4
|
-
//! The clawback operation uses SAC clawback, which requires AUTH_CLAWBACK_ENABLED
|
|
5
|
-
//! flag on the SAC issuer.
|
|
3
|
+
//! Operator must hold CLAWBACK_ROLE. SAC must have AUTH_CLAWBACK_ENABLED.
|
|
6
4
|
|
|
7
5
|
use super::test_helper::mock_clawback_auth;
|
|
8
6
|
use crate::tests::test_helper::{mock_oft_mint_auth, TestSetup};
|
|
9
7
|
use soroban_sdk::testutils::IssuerFlags;
|
|
10
8
|
|
|
11
9
|
// =========================================================================
|
|
12
|
-
// clawback Tests
|
|
10
|
+
// clawback Tests
|
|
13
11
|
// =========================================================================
|
|
14
12
|
|
|
15
13
|
#[test]
|
|
@@ -25,7 +23,7 @@ fn test_clawback_by_owner() {
|
|
|
25
23
|
assert_eq!(setup.sac_client.balance(&user), 1000);
|
|
26
24
|
|
|
27
25
|
mock_clawback_auth(&setup, &setup.owner, &user, 500_i128);
|
|
28
|
-
setup.sac_manager_client.clawback(&user, &500);
|
|
26
|
+
setup.sac_manager_client.clawback(&user, &500, &setup.owner);
|
|
29
27
|
assert_eq!(setup.sac_client.balance(&user), 500);
|
|
30
28
|
}
|
|
31
29
|
|
|
@@ -41,7 +39,7 @@ fn test_clawback_full_balance() {
|
|
|
41
39
|
setup.sac_manager_client.mint(&user, &1000, &setup.minter);
|
|
42
40
|
|
|
43
41
|
mock_clawback_auth(&setup, &setup.owner, &user, 1000_i128);
|
|
44
|
-
setup.sac_manager_client.clawback(&user, &1000);
|
|
42
|
+
setup.sac_manager_client.clawback(&user, &1000, &setup.owner);
|
|
45
43
|
assert_eq!(setup.sac_client.balance(&user), 0);
|
|
46
44
|
}
|
|
47
45
|
|
|
@@ -57,18 +55,18 @@ fn test_clawback_fails_when_amount_exceeds_balance() {
|
|
|
57
55
|
setup.sac_manager_client.mint(&user, &100, &setup.minter);
|
|
58
56
|
|
|
59
57
|
mock_clawback_auth(&setup, &setup.owner, &user, 200_i128);
|
|
60
|
-
let result = setup.sac_manager_client.try_clawback(&user, &200);
|
|
58
|
+
let result = setup.sac_manager_client.try_clawback(&user, &200, &setup.owner);
|
|
61
59
|
assert!(result.is_err());
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
#[test]
|
|
65
|
-
fn
|
|
63
|
+
fn test_clawback_operator_without_role_fails() {
|
|
66
64
|
let setup = TestSetup::new().with_manager_as_sac_admin().build();
|
|
67
65
|
let user = setup.generate_address();
|
|
68
66
|
let random = setup.generate_address();
|
|
69
67
|
|
|
70
68
|
mock_clawback_auth(&setup, &random, &user, 500_i128);
|
|
71
|
-
let result = setup.sac_manager_client.try_clawback(&user, &500);
|
|
69
|
+
let result = setup.sac_manager_client.try_clawback(&user, &500, &random);
|
|
72
70
|
assert!(result.is_err());
|
|
73
71
|
}
|
|
74
72
|
|
|
@@ -82,5 +80,5 @@ fn test_clawback_fails_without_auth() {
|
|
|
82
80
|
let setup = TestSetup::new().build();
|
|
83
81
|
let user = setup.generate_address();
|
|
84
82
|
|
|
85
|
-
setup.sac_manager_client.clawback(&user, &300);
|
|
83
|
+
setup.sac_manager_client.clawback(&user, &300, &setup.owner);
|
|
86
84
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
//! Mint (Mintable) Integration Tests
|
|
2
2
|
//!
|
|
3
|
-
//!
|
|
4
|
-
//! authorization (operation must be in minters, operation must auth), and error cases.
|
|
3
|
+
//! Operator must hold MINTER_ROLE and authorize the call.
|
|
5
4
|
|
|
6
|
-
use crate::errors::SacManagerError;
|
|
7
5
|
use crate::tests::test_helper::{mock_auth, mock_oft_mint_auth, TestSetup};
|
|
8
6
|
|
|
9
7
|
// =========================================================================
|
|
10
|
-
// Mint success —
|
|
8
|
+
// Mint success — operator with MINTER_ROLE calls mint
|
|
11
9
|
// =========================================================================
|
|
12
10
|
|
|
13
11
|
#[test]
|
|
@@ -21,31 +19,28 @@ fn test_mint_by_minter() {
|
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
// =========================================================================
|
|
24
|
-
// Mint
|
|
22
|
+
// Mint role auth — operator without MINTER_ROLE fails
|
|
25
23
|
// =========================================================================
|
|
26
24
|
|
|
27
25
|
#[test]
|
|
28
|
-
fn
|
|
29
|
-
let setup = TestSetup::new().with_empty_minters().build();
|
|
30
|
-
let recipient = setup.generate_address();
|
|
31
|
-
|
|
32
|
-
let result = setup.sac_manager_client.try_mint(&recipient, &1000, &setup.minter);
|
|
33
|
-
assert_eq!(result.err().unwrap().unwrap(), SacManagerError::Unauthorized.into());
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
#[test]
|
|
37
|
-
fn test_mint_by_non_minter_fails() {
|
|
26
|
+
fn test_mint_operator_without_role_fails() {
|
|
38
27
|
let setup = TestSetup::new().with_manager_as_sac_admin().build();
|
|
39
28
|
let recipient = setup.generate_address();
|
|
40
29
|
let random = setup.generate_address();
|
|
41
30
|
|
|
42
|
-
mock_auth(
|
|
31
|
+
mock_auth(
|
|
32
|
+
&setup.env,
|
|
33
|
+
&setup.sac_manager,
|
|
34
|
+
&random,
|
|
35
|
+
"mint",
|
|
36
|
+
(&recipient, 1000_i128, &random),
|
|
37
|
+
);
|
|
43
38
|
let result = setup.sac_manager_client.try_mint(&recipient, &1000, &random);
|
|
44
|
-
|
|
39
|
+
assert!(result.is_err());
|
|
45
40
|
}
|
|
46
41
|
|
|
47
42
|
// =========================================================================
|
|
48
|
-
// Mint auth
|
|
43
|
+
// Mint auth — operator must authorize
|
|
49
44
|
// =========================================================================
|
|
50
45
|
|
|
51
46
|
#[test]
|
|
@@ -1,36 +1,46 @@
|
|
|
1
|
-
//!
|
|
1
|
+
//! set_admin Integration Tests
|
|
2
|
+
//!
|
|
3
|
+
//! Tests that set_admin requires ADMIN_MANAGER_ROLE on the operator.
|
|
2
4
|
|
|
3
|
-
use super::test_helper::
|
|
5
|
+
use super::test_helper::mock_set_admin_auth;
|
|
4
6
|
use crate::tests::test_helper::TestSetup;
|
|
5
7
|
|
|
6
8
|
// =========================================================================
|
|
7
|
-
//
|
|
9
|
+
// set_admin Tests
|
|
8
10
|
// =========================================================================
|
|
9
11
|
|
|
10
12
|
#[test]
|
|
11
|
-
fn
|
|
13
|
+
fn test_set_admin_by_owner() {
|
|
12
14
|
let setup = TestSetup::new().with_manager_as_sac_admin().build();
|
|
13
15
|
let new_admin = setup.generate_address();
|
|
14
16
|
|
|
15
|
-
// Current SAC admin is the manager (configured by test setup).
|
|
16
17
|
assert_eq!(setup.sac_client.admin(), setup.sac_manager);
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
setup.sac_manager_client.release_sac_admin(&new_admin);
|
|
19
|
+
mock_set_admin_auth(&setup, &setup.owner, &new_admin);
|
|
20
|
+
setup.sac_manager_client.set_admin(&new_admin, &setup.owner);
|
|
21
21
|
assert_eq!(setup.sac_client.admin(), new_admin);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// =========================================================================
|
|
25
|
-
//
|
|
25
|
+
// set_admin Role Auth Tests
|
|
26
26
|
// =========================================================================
|
|
27
27
|
|
|
28
|
+
#[test]
|
|
29
|
+
fn test_set_admin_operator_without_role_fails() {
|
|
30
|
+
let setup = TestSetup::new().with_manager_as_sac_admin().build();
|
|
31
|
+
let new_admin = setup.generate_address();
|
|
32
|
+
let random = setup.generate_address();
|
|
33
|
+
|
|
34
|
+
mock_set_admin_auth(&setup, &random, &new_admin);
|
|
35
|
+
let result = setup.sac_manager_client.try_set_admin(&new_admin, &random);
|
|
36
|
+
assert!(result.is_err());
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
#[test]
|
|
29
40
|
#[should_panic(expected = "Error(Auth, InvalidAction)")]
|
|
30
|
-
fn
|
|
41
|
+
fn test_set_admin_without_auth() {
|
|
31
42
|
let setup = TestSetup::new().build();
|
|
32
43
|
let new_admin = setup.generate_address();
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
setup.sac_manager_client.release_sac_admin(&new_admin);
|
|
45
|
+
setup.sac_manager_client.set_admin(&new_admin, &setup.owner);
|
|
36
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//! set_authorized Integration Tests
|
|
2
2
|
//!
|
|
3
|
-
//! Requires revocable issuer flag on the SAC
|
|
3
|
+
//! Requires revocable issuer flag on the SAC. Operator must hold BLACKLISTER_ROLE.
|
|
4
4
|
|
|
5
5
|
use super::test_helper::mock_set_authorized_auth;
|
|
6
6
|
use crate::tests::test_helper::TestSetup;
|
|
@@ -15,29 +15,39 @@ fn test_set_authorized_by_owner() {
|
|
|
15
15
|
let setup = TestSetup::new().with_manager_as_sac_admin().build();
|
|
16
16
|
let user = setup.generate_address();
|
|
17
17
|
|
|
18
|
-
// Enable issuer flag required by SAC for set_authorized.
|
|
19
18
|
setup.sac_contract.issuer().set_flag(IssuerFlags::RevocableFlag);
|
|
20
19
|
assert!(setup.sac_client.authorized(&user));
|
|
21
20
|
|
|
22
|
-
mock_set_authorized_auth(&setup, &user, false);
|
|
23
|
-
setup.sac_manager_client.set_authorized(&user, &false);
|
|
21
|
+
mock_set_authorized_auth(&setup, &setup.owner, &user, false);
|
|
22
|
+
setup.sac_manager_client.set_authorized(&user, &false, &setup.owner);
|
|
24
23
|
assert!(!setup.sac_client.authorized(&user));
|
|
25
24
|
|
|
26
|
-
mock_set_authorized_auth(&setup, &user, true);
|
|
27
|
-
setup.sac_manager_client.set_authorized(&user, &true);
|
|
25
|
+
mock_set_authorized_auth(&setup, &setup.owner, &user, true);
|
|
26
|
+
setup.sac_manager_client.set_authorized(&user, &true, &setup.owner);
|
|
28
27
|
assert!(setup.sac_client.authorized(&user));
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
// =========================================================================
|
|
32
|
-
// set_authorized Auth Tests
|
|
31
|
+
// set_authorized Role Auth Tests
|
|
33
32
|
// =========================================================================
|
|
34
33
|
|
|
34
|
+
#[test]
|
|
35
|
+
fn test_set_authorized_operator_without_role_fails() {
|
|
36
|
+
let setup = TestSetup::new().with_manager_as_sac_admin().build();
|
|
37
|
+
let user = setup.generate_address();
|
|
38
|
+
let random = setup.generate_address();
|
|
39
|
+
|
|
40
|
+
setup.sac_contract.issuer().set_flag(IssuerFlags::RevocableFlag);
|
|
41
|
+
mock_set_authorized_auth(&setup, &random, &user, false);
|
|
42
|
+
let result = setup.sac_manager_client.try_set_authorized(&user, &false, &random);
|
|
43
|
+
assert!(result.is_err());
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
#[test]
|
|
36
47
|
#[should_panic(expected = "Error(Auth, InvalidAction)")]
|
|
37
48
|
fn test_set_authorized_without_auth() {
|
|
38
49
|
let setup = TestSetup::new().build();
|
|
39
50
|
let user = setup.generate_address();
|
|
40
51
|
|
|
41
|
-
|
|
42
|
-
setup.sac_manager_client.set_authorized(&user, &false);
|
|
52
|
+
setup.sac_manager_client.set_authorized(&user, &false, &setup.owner);
|
|
43
53
|
}
|
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
use crate::tests::test_helper::{mock_auth, TestSetup};
|
|
2
2
|
use soroban_sdk::Address;
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/// Mock auth for `clawback(from, amount, operator)` — operator must hold CLAWBACK_ROLE.
|
|
5
|
+
pub fn mock_clawback_auth(setup: &TestSetup, operator: &Address, from: &Address, amount: i128) {
|
|
6
|
+
mock_auth(
|
|
7
|
+
&setup.env,
|
|
8
|
+
&setup.sac_manager,
|
|
9
|
+
operator,
|
|
10
|
+
"clawback",
|
|
11
|
+
(from, amount, operator),
|
|
12
|
+
);
|
|
6
13
|
}
|
|
7
14
|
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
/// Mock auth for `set_authorized(id, authorize, operator)` — operator must hold BLACKLISTER_ROLE.
|
|
16
|
+
pub fn mock_set_authorized_auth(setup: &TestSetup, operator: &Address, user: &Address, authorize: bool) {
|
|
17
|
+
mock_auth(
|
|
18
|
+
&setup.env,
|
|
19
|
+
&setup.sac_manager,
|
|
20
|
+
operator,
|
|
21
|
+
"set_authorized",
|
|
22
|
+
(user, authorize, operator),
|
|
23
|
+
);
|
|
10
24
|
}
|
|
11
25
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
/// Mock auth for `set_admin(new_admin, operator)` — operator must hold ADMIN_MANAGER_ROLE.
|
|
27
|
+
pub fn mock_set_admin_auth(setup: &TestSetup, operator: &Address, new_admin: &Address) {
|
|
28
|
+
mock_auth(
|
|
29
|
+
&setup.env,
|
|
30
|
+
&setup.sac_manager,
|
|
31
|
+
operator,
|
|
32
|
+
"set_admin",
|
|
33
|
+
(new_admin, operator),
|
|
34
|
+
);
|
|
18
35
|
}
|
|
@@ -11,18 +11,3 @@ fn test_underlying_sac() {
|
|
|
11
11
|
let setup = TestSetup::new().build();
|
|
12
12
|
assert_eq!(setup.sac_manager_client.underlying_sac(), setup.sac);
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
#[test]
|
|
16
|
-
fn test_minters() {
|
|
17
|
-
let setup = TestSetup::new().build();
|
|
18
|
-
let minters = setup.sac_manager_client.minters();
|
|
19
|
-
assert_eq!(minters.len(), 1);
|
|
20
|
-
assert_eq!(minters.get(0), Some(setup.minter.clone()));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
#[test]
|
|
24
|
-
fn test_minters_empty_when_not_set() {
|
|
25
|
-
let setup = TestSetup::new().with_empty_minters().build();
|
|
26
|
-
let minters = setup.sac_manager_client.minters();
|
|
27
|
-
assert_eq!(minters.len(), 0);
|
|
28
|
-
}
|