diff --git a/Cargo.lock b/Cargo.lock index b78cb150..d3da0909 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2302,6 +2302,7 @@ version = "0.0.0" dependencies = [ "chain-factory", "multiversx-sc", + "multiversx-sc-modules", "multiversx-sc-scenario", "num-bigint", "proxies", diff --git a/common/proxies/src/token_handler_proxy.rs b/common/proxies/src/token_handler_proxy.rs index 319f4ad4..8e27c2a4 100644 --- a/common/proxies/src/token_handler_proxy.rs +++ b/common/proxies/src/token_handler_proxy.rs @@ -43,12 +43,16 @@ where From: TxFrom, Gas: TxGas, { - pub fn init( + pub fn init< + Arg0: ProxyArg>, + >( self, + chain_factory_master: Arg0, ) -> TxTypedDeploy { self.wrapped_tx .payment(NotPayable) .raw_deploy() + .argument(&chain_factory_master) .original_result() } } @@ -111,4 +115,52 @@ where .argument(&tokens) .original_result() } + + pub fn is_admin< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isAdmin") + .argument(&address) + .original_result() + } + + pub fn add_admin< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("addAdmin") + .argument(&address) + .original_result() + } + + pub fn remove_admin< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("removeAdmin") + .argument(&address) + .original_result() + } + + pub fn admins( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getAdmins") + .original_result() + } } diff --git a/enshrine-esdt-safe/interactor/src/enshrine_esdt_safe_interactor.rs b/enshrine-esdt-safe/interactor/src/enshrine_esdt_safe_interactor.rs index 2a673bef..7d342d44 100644 --- a/enshrine-esdt-safe/interactor/src/enshrine_esdt_safe_interactor.rs +++ b/enshrine-esdt-safe/interactor/src/enshrine_esdt_safe_interactor.rs @@ -188,6 +188,7 @@ impl ContractInteract { pub async fn deploy_token_handler(&mut self) { let token_handler_code_path = MxscPath::new(&self.token_handler_code); + let chain_factory_address = Bech32Address::from_bech32_string("chain_factory".to_string()); let new_address = self .interactor @@ -195,7 +196,7 @@ impl ContractInteract { .from(&self.wallet_address) .gas(100_000_000u64) .typed(token_handler_proxy::TokenHandlerProxy) - .init() + .init(chain_factory_address) .code(token_handler_code_path) .returns(ReturnsNewAddress) .run() diff --git a/enshrine-esdt-safe/tests/enshrine_esdt_safe_blackbox_test.rs b/enshrine-esdt-safe/tests/enshrine_esdt_safe_blackbox_test.rs index 85f8a3d5..c8a629f0 100644 --- a/enshrine-esdt-safe/tests/enshrine_esdt_safe_blackbox_test.rs +++ b/enshrine-esdt-safe/tests/enshrine_esdt_safe_blackbox_test.rs @@ -183,7 +183,7 @@ impl EnshrineTestState { .tx() .from(ENSHRINE_ESDT_OWNER_ADDRESS) .typed(TokenHandlerProxy) - .init() + .init(ENSHRINE_ESDT_ADDRESS) .code(TOKEN_HANDLER_CODE_PATH) .new_address(TOKEN_HANDLER_ADDRESS) .run(); @@ -391,7 +391,7 @@ impl EnshrineTestState { fn propose_whitelist_enshrine_esdt(&mut self) { self.world .tx() - .from(ENSHRINE_ESDT_OWNER_ADDRESS) + .from(ENSHRINE_ESDT_ADDRESS) .to(TOKEN_HANDLER_ADDRESS) .typed(TokenHandlerProxy) .whitelist_enshrine_esdt(ENSHRINE_ESDT_ADDRESS) diff --git a/enshrine-esdt-safe/wasm-enshrine-esdt-safe-full/Cargo.lock b/enshrine-esdt-safe/wasm-enshrine-esdt-safe-full/Cargo.lock index 5d4e4e6f..def5794b 100644 --- a/enshrine-esdt-safe/wasm-enshrine-esdt-safe-full/Cargo.lock +++ b/enshrine-esdt-safe/wasm-enshrine-esdt-safe-full/Cargo.lock @@ -277,6 +277,7 @@ version = "0.0.0" dependencies = [ "chain-factory", "multiversx-sc", + "multiversx-sc-modules", "proxies", "transaction", ] diff --git a/enshrine-esdt-safe/wasm-enshrine-esdt-safe-view/Cargo.lock b/enshrine-esdt-safe/wasm-enshrine-esdt-safe-view/Cargo.lock index 0a11f9d8..8650b5b8 100644 --- a/enshrine-esdt-safe/wasm-enshrine-esdt-safe-view/Cargo.lock +++ b/enshrine-esdt-safe/wasm-enshrine-esdt-safe-view/Cargo.lock @@ -277,6 +277,7 @@ version = "0.0.0" dependencies = [ "chain-factory", "multiversx-sc", + "multiversx-sc-modules", "proxies", "transaction", ] diff --git a/enshrine-esdt-safe/wasm/Cargo.lock b/enshrine-esdt-safe/wasm/Cargo.lock index b2aec657..56b8fc5f 100644 --- a/enshrine-esdt-safe/wasm/Cargo.lock +++ b/enshrine-esdt-safe/wasm/Cargo.lock @@ -277,6 +277,7 @@ version = "0.0.0" dependencies = [ "chain-factory", "multiversx-sc", + "multiversx-sc-modules", "proxies", "transaction", ] diff --git a/token-handler/Cargo.toml b/token-handler/Cargo.toml index cb76598b..c2ee9be1 100644 --- a/token-handler/Cargo.toml +++ b/token-handler/Cargo.toml @@ -20,6 +20,9 @@ path = "../chain-factory" [dependencies.multiversx-sc] version = "=0.54.6" +[dependencies.multiversx-sc-modules] +version = "=0.54.6" + [dev-dependencies] num-bigint = "0.4" diff --git a/token-handler/src/lib.rs b/token-handler/src/lib.rs index b2738694..85dfe5e7 100644 --- a/token-handler/src/lib.rs +++ b/token-handler/src/lib.rs @@ -2,21 +2,26 @@ #[allow(unused_imports)] use multiversx_sc::imports::*; +use multiversx_sc_modules::only_admin; pub mod common_storage; pub mod transfer_tokens; #[multiversx_sc::contract] pub trait TokenHandler: - transfer_tokens::TransferTokensModule + common_storage::CommonStorage + transfer_tokens::TransferTokensModule + common_storage::CommonStorage + only_admin::OnlyAdminModule { #[init] - fn init(&self) {} + fn init(&self, chain_factory_master: ManagedAddress) { + self.blockchain().is_smart_contract(&chain_factory_master); + + self.add_admin(chain_factory_master); + } #[upgrade] fn upgrade(&self) {} - #[only_owner] + #[only_admin] #[endpoint(whitelistEnshrineEsdt)] fn whitelist_enshrine_esdt(&self, enshrine_esdt_address: ManagedAddress) { require!( diff --git a/token-handler/tests/token_handler_blackbox_tests.rs b/token-handler/tests/token_handler_blackbox_tests.rs index b92a288b..d74c5a54 100644 --- a/token-handler/tests/token_handler_blackbox_tests.rs +++ b/token-handler/tests/token_handler_blackbox_tests.rs @@ -3,7 +3,7 @@ use multiversx_sc::types::{ MultiValueEncoded, TestAddress, TestSCAddress, TestTokenIdentifier, }; use multiversx_sc_scenario::{api::StaticApi, imports::MxscPath, ScenarioWorld}; -use multiversx_sc_scenario::{ExpectError, ScenarioTxRun}; +use multiversx_sc_scenario::{ExpectError, ReturnsHandledOrError, ScenarioTxRun}; use proxies::chain_factory_proxy::ChainFactoryContractProxy; use proxies::token_handler_proxy::TokenHandlerProxy; use transaction::{OperationEsdtPayment, TransferData}; @@ -25,11 +25,6 @@ const _PREFIX_NFT_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("sov- const WEGLD_BALANCE: u128 = 100_000_000_000_000_000; -pub struct ErrorStatus<'a> { - code: u64, - message: &'a str, -} - fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); @@ -71,7 +66,7 @@ impl TokenHandlerTestState { .tx() .from(OWNER_ADDRESS) .typed(TokenHandlerProxy) - .init() + .init(FACTORY_ADDRESS) .code(TOKEN_HANDLER_CODE_PATH) .new_address(TOKEN_HANDLER_ADDRESS) .run(); @@ -131,28 +126,21 @@ impl TokenHandlerTestState { fn propose_whitelist_caller( &mut self, - caller: TestAddress, enshrine_address: TestSCAddress, - error: Option, + error_message: Option<&str>, ) { - match error { - None => self - .world - .tx() - .to(TOKEN_HANDLER_ADDRESS) - .from(caller) - .typed(TokenHandlerProxy) - .whitelist_enshrine_esdt(enshrine_address) - .run(), - Some(error_status) => self - .world - .tx() - .to(TOKEN_HANDLER_ADDRESS) - .from(caller) - .typed(TokenHandlerProxy) - .whitelist_enshrine_esdt(enshrine_address) - .returns(ExpectError(error_status.code, error_status.message)) - .run(), + let response = self + .world + .tx() + .to(TOKEN_HANDLER_ADDRESS) + .from(enshrine_address) + .typed(TokenHandlerProxy) + .whitelist_enshrine_esdt(enshrine_address) + .returns(ReturnsHandledOrError::new()) + .run(); + + if let Err(error) = response { + assert_eq!(error_message, Some(error.message.as_str())) } } @@ -186,23 +174,22 @@ fn test_deploy() { } #[test] -fn test_whitelist_ensrhine_esdt_caller_not_owner() { +fn test_whitelist_enshrine_esdt_caller_not_admin() { let mut state = TokenHandlerTestState::new(); - let error = ErrorStatus { - code: 4, - message: "Endpoint can only be called by owner", - }; + let error_message = "Endpoint can only be called by admins"; state.propose_deploy_token_handler(); - state.propose_whitelist_caller(USER_ADDRESS, FACTORY_ADDRESS, Some(error)); + state.propose_deploy_factory_sc(); + state.propose_whitelist_caller(TOKEN_HANDLER_ADDRESS, Some(error_message)); } #[test] -fn test_whitelist_ensrhine() { +fn test_whitelist_enshrine() { let mut state = TokenHandlerTestState::new(); state.propose_deploy_token_handler(); - state.propose_whitelist_caller(OWNER_ADDRESS, FACTORY_ADDRESS, None); + state.propose_deploy_factory_sc(); + state.propose_whitelist_caller(FACTORY_ADDRESS, None); } // NOTE: @@ -226,7 +213,7 @@ fn test_transfer_tokens_no_payment() { .world .set_esdt_balance(FACTORY_ADDRESS, b"FUNGIBLE_TOKEN_ID", 100); - state.propose_whitelist_caller(OWNER_ADDRESS, FACTORY_ADDRESS, None); + state.propose_whitelist_caller(FACTORY_ADDRESS, None); state.world.set_esdt_local_roles( TOKEN_HANDLER_ADDRESS, diff --git a/token-handler/wasm-token-handler-full/Cargo.lock b/token-handler/wasm-token-handler-full/Cargo.lock index a4ab4c4e..9dc04a79 100644 --- a/token-handler/wasm-token-handler-full/Cargo.lock +++ b/token-handler/wasm-token-handler-full/Cargo.lock @@ -224,6 +224,7 @@ version = "0.0.0" dependencies = [ "chain-factory", "multiversx-sc", + "multiversx-sc-modules", "proxies", "transaction", ] diff --git a/token-handler/wasm-token-handler-full/src/lib.rs b/token-handler/wasm-token-handler-full/src/lib.rs index f03013a9..76eb9820 100644 --- a/token-handler/wasm-token-handler-full/src/lib.rs +++ b/token-handler/wasm-token-handler-full/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 2 +// Endpoints: 6 // Async Callback (empty): 1 -// Total number of exported functions: 5 +// Total number of exported functions: 9 #![no_std] @@ -22,6 +22,10 @@ multiversx_sc_wasm_adapter::endpoints! { upgrade => upgrade whitelistEnshrineEsdt => whitelist_enshrine_esdt transferTokens => transfer_tokens + isAdmin => is_admin + addAdmin => add_admin + removeAdmin => remove_admin + getAdmins => admins ) } diff --git a/token-handler/wasm-token-handler-view/Cargo.lock b/token-handler/wasm-token-handler-view/Cargo.lock index 873bd496..c09c712a 100644 --- a/token-handler/wasm-token-handler-view/Cargo.lock +++ b/token-handler/wasm-token-handler-view/Cargo.lock @@ -224,6 +224,7 @@ version = "0.0.0" dependencies = [ "chain-factory", "multiversx-sc", + "multiversx-sc-modules", "proxies", "transaction", ] diff --git a/token-handler/wasm/Cargo.lock b/token-handler/wasm/Cargo.lock index fe395276..9859b2f6 100644 --- a/token-handler/wasm/Cargo.lock +++ b/token-handler/wasm/Cargo.lock @@ -224,6 +224,7 @@ version = "0.0.0" dependencies = [ "chain-factory", "multiversx-sc", + "multiversx-sc-modules", "proxies", "transaction", ] diff --git a/token-handler/wasm/src/lib.rs b/token-handler/wasm/src/lib.rs index f03013a9..76eb9820 100644 --- a/token-handler/wasm/src/lib.rs +++ b/token-handler/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 2 +// Endpoints: 6 // Async Callback (empty): 1 -// Total number of exported functions: 5 +// Total number of exported functions: 9 #![no_std] @@ -22,6 +22,10 @@ multiversx_sc_wasm_adapter::endpoints! { upgrade => upgrade whitelistEnshrineEsdt => whitelist_enshrine_esdt transferTokens => transfer_tokens + isAdmin => is_admin + addAdmin => add_admin + removeAdmin => remove_admin + getAdmins => admins ) }