diff --git a/Cargo.lock b/Cargo.lock index 0ea11bc1..42e992aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,24 +230,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" -[[package]] -name = "bridged-tokens-wrapper" -version = "0.0.0" -dependencies = [ - "multiversx-sc", - "multiversx-sc-modules", - "multiversx-sc-scenario", - "transaction", -] - -[[package]] -name = "bridged-tokens-wrapper-meta" -version = "0.0.0" -dependencies = [ - "bridged-tokens-wrapper", - "multiversx-sc-meta", -] - [[package]] name = "bstr" version = "1.6.2" @@ -1209,7 +1191,6 @@ dependencies = [ name = "multi-transfer-esdt" version = "0.0.0" dependencies = [ - "bridged-tokens-wrapper", "max-bridged-amount-module", "multiversx-sc", "multiversx-sc-scenario", @@ -1225,29 +1206,6 @@ dependencies = [ "multiversx-sc-meta", ] -[[package]] -name = "multisig" -version = "0.0.0" -dependencies = [ - "esdt-safe", - "max-bridged-amount-module", - "multi-transfer-esdt", - "multiversx-sc", - "multiversx-sc-modules", - "multiversx-sc-scenario", - "token-module", - "transaction", - "tx-batch-module", -] - -[[package]] -name = "multisig-meta" -version = "0.0.0" -dependencies = [ - "multisig", - "multiversx-sc-meta", -] - [[package]] name = "multiversx-chain-scenario-format" version = "0.20.0" diff --git a/Cargo.toml b/Cargo.toml index f9432301..fd492591 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,5 @@ members = [ "esdt-safe", "esdt-safe/meta", "multi-transfer-esdt", - "multi-transfer-esdt/meta", - "multisig", - "multisig/meta", - "bridged-tokens-wrapper", - "bridged-tokens-wrapper/meta" + "multi-transfer-esdt/meta" ] diff --git a/bridged-tokens-wrapper/.gitignore b/bridged-tokens-wrapper/.gitignore deleted file mode 100644 index ced1b927..00000000 --- a/bridged-tokens-wrapper/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ -*/target/ - -# The mxpy output -output* diff --git a/bridged-tokens-wrapper/Cargo.toml b/bridged-tokens-wrapper/Cargo.toml deleted file mode 100644 index 00f6e14b..00000000 --- a/bridged-tokens-wrapper/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "bridged-tokens-wrapper" -version = "0.0.0" -authors = ["Alin Cruceat "] -edition = "2018" -publish = false - -[lib] -path = "src/lib.rs" - -[dependencies.transaction] -path = "../common/transaction" - -[dependencies.multiversx-sc] -version = "0.43.4" - -[dependencies.multiversx-sc-modules] -version = "0.43.4" - -[dev-dependencies.multiversx-sc-scenario] -version = "0.43.4" diff --git a/bridged-tokens-wrapper/meta/Cargo.toml b/bridged-tokens-wrapper/meta/Cargo.toml deleted file mode 100644 index 345bcb30..00000000 --- a/bridged-tokens-wrapper/meta/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "bridged-tokens-wrapper-meta" -version = "0.0.0" -edition = "2018" -publish = false -[dependencies.bridged-tokens-wrapper] -path = ".." - -[dependencies.multiversx-sc-meta] -version = "0.43.4" diff --git a/bridged-tokens-wrapper/meta/src/main.rs b/bridged-tokens-wrapper/meta/src/main.rs deleted file mode 100644 index ac93d248..00000000 --- a/bridged-tokens-wrapper/meta/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - multiversx_sc_meta::cli_main::(); -} diff --git a/bridged-tokens-wrapper/multiversx.json b/bridged-tokens-wrapper/multiversx.json deleted file mode 100644 index 73655396..00000000 --- a/bridged-tokens-wrapper/multiversx.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "language": "rust" -} \ No newline at end of file diff --git a/bridged-tokens-wrapper/src/dfp_big_uint.rs b/bridged-tokens-wrapper/src/dfp_big_uint.rs deleted file mode 100644 index a70839f5..00000000 --- a/bridged-tokens-wrapper/src/dfp_big_uint.rs +++ /dev/null @@ -1,44 +0,0 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); - -#[derive(Clone, PartialEq, Eq)] -pub struct DFPBigUint { - bu: BigUint, - num_decimals: u32, -} - -impl DFPBigUint { - pub fn from_raw(bu: BigUint, num_decimals: u32) -> Self { - DFPBigUint { bu, num_decimals } - } - - pub fn convert(self, decimals: u32) -> Self { - if self.num_decimals == decimals { - return self; - } - - let new_bu = if self.num_decimals > decimals { - let diff_decimals = self.num_decimals - decimals; - self.bu / 10u64.pow(diff_decimals) - } else { - let diff_decimals = decimals - self.num_decimals; - self.bu * 10u64.pow(diff_decimals) - }; - - DFPBigUint { - bu: new_bu, - num_decimals: decimals, - } - } - - pub fn trunc(&self) -> Self { - DFPBigUint { - bu: self.bu.clone() / 10u64.pow(self.num_decimals), - num_decimals: 1, - } - } - - pub fn to_raw(&self) -> BigUint { - self.bu.clone() - } -} diff --git a/bridged-tokens-wrapper/src/lib.rs b/bridged-tokens-wrapper/src/lib.rs deleted file mode 100644 index e1727e75..00000000 --- a/bridged-tokens-wrapper/src/lib.rs +++ /dev/null @@ -1,289 +0,0 @@ -#![no_std] - -mod dfp_big_uint; -use core::ops::Deref; - -pub use dfp_big_uint::DFPBigUint; -use transaction::PaymentsVec; - -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); - -impl DFPBigUint {} - -#[multiversx_sc::contract] -pub trait BridgedTokensWrapper: multiversx_sc_modules::pause::PauseModule { - #[init] - fn init(&self) { - self.set_paused(true); - } - - #[endpoint] - fn upgrade(&self) {} - - #[only_owner] - #[endpoint(addWrappedToken)] - fn add_wrapped_token(&self, universal_bridged_token_ids: TokenIdentifier, num_decimals: u32) { - self.require_mint_and_burn_roles(&universal_bridged_token_ids); - self.token_decimals_num(&universal_bridged_token_ids) - .set(num_decimals); - self.universal_bridged_token_ids() - .insert(universal_bridged_token_ids); - } - - #[only_owner] - #[endpoint(updateWrappedToken)] - fn update_wrapped_token( - &self, - universal_bridged_token_ids: TokenIdentifier, - num_decimals: u32, - ) { - require!( - self.universal_bridged_token_ids() - .contains(&universal_bridged_token_ids), - "Universal token was not added yet" - ); - self.token_decimals_num(&universal_bridged_token_ids) - .set(num_decimals); - } - - #[only_owner] - #[endpoint(removeWrappedToken)] - fn remove_wrapped_token(&self, universal_bridged_token_ids: TokenIdentifier) { - let _ = self - .universal_bridged_token_ids() - .swap_remove(&universal_bridged_token_ids); - - let mut chain_specific_tokens = self.chain_specific_token_ids(&universal_bridged_token_ids); - for token in chain_specific_tokens.iter() { - self.chain_specific_to_universal_mapping(&token).clear(); - self.token_decimals_num(&token).clear(); - } - - chain_specific_tokens.clear(); - self.token_decimals_num(&universal_bridged_token_ids) - .clear(); - } - - #[only_owner] - #[endpoint(whitelistToken)] - fn whitelist_token( - &self, - chain_specific_token_id: TokenIdentifier, - chain_specific_token_decimals: u32, - universal_bridged_token_ids: TokenIdentifier, - ) { - self.require_mint_and_burn_roles(&universal_bridged_token_ids); - - let chain_to_universal_mapper = - self.chain_specific_to_universal_mapping(&chain_specific_token_id); - require!( - chain_to_universal_mapper.is_empty(), - "Chain-specific token is already mapped to another universal token" - ); - - self.token_decimals_num(&chain_specific_token_id) - .set(chain_specific_token_decimals); - - chain_to_universal_mapper.set(&universal_bridged_token_ids); - - let _ = self - .chain_specific_token_ids(&universal_bridged_token_ids) - .insert(chain_specific_token_id); - - self.universal_bridged_token_ids() - .insert(universal_bridged_token_ids); - } - - #[only_owner] - #[endpoint(updateWhitelistedToken)] - fn update_whitelisted_token( - &self, - chain_specific_token_id: TokenIdentifier, - chain_specific_token_decimals: u32, - ) { - let chain_to_universal_mapper = - self.chain_specific_to_universal_mapping(&chain_specific_token_id); - require!( - !chain_to_universal_mapper.is_empty(), - "Chain-specific token was not whitelisted yet" - ); - - self.token_decimals_num(&chain_specific_token_id) - .set(chain_specific_token_decimals); - } - - #[only_owner] - #[endpoint(blacklistToken)] - fn blacklist_token(&self, chain_specific_token_id: TokenIdentifier) { - let chain_to_universal_mapper = - self.chain_specific_to_universal_mapping(&chain_specific_token_id); - - let universal_bridged_token_ids = chain_to_universal_mapper.get(); - - let _ = self - .chain_specific_token_ids(&universal_bridged_token_ids) - .swap_remove(&chain_specific_token_id); - - chain_to_universal_mapper.clear(); - self.token_decimals_num(&chain_specific_token_id).clear(); - } - - #[payable("*")] - #[endpoint(depositLiquidity)] - fn deposit_liquidity(&self) { - let (payment_token, payment_amount) = self.call_value().single_fungible_esdt(); - self.token_liquidity(&payment_token) - .update(|liq| *liq += payment_amount); - } - - /// Will wrap what it can, and send back the rest unchanged - #[payable("*")] - #[endpoint(wrapTokens)] - fn wrap_tokens(&self) -> PaymentsVec { - require!(self.not_paused(), "Contract is paused"); - let original_payments = self.call_value().all_esdt_transfers().deref().clone(); - if original_payments.is_empty() { - return original_payments; - } - - let mut new_payments = ManagedVec::new(); - - for payment in &original_payments { - let universal_token_id_mapper = - self.chain_specific_to_universal_mapping(&payment.token_identifier); - - // if there is chain specific -> universal mapping, then the token is whitelisted - if universal_token_id_mapper.is_empty() { - new_payments.push(payment); - continue; - } - let universal_token_id = universal_token_id_mapper.get(); - self.require_tokens_have_set_decimals_num( - &universal_token_id, - &payment.token_identifier, - ); - self.token_liquidity(&payment.token_identifier) - .update(|value| *value += &payment.amount); - let converted_amount = self.get_converted_amount( - &payment.token_identifier, - &universal_token_id, - payment.amount, - ); - - self.send() - .esdt_local_mint(&universal_token_id, 0, &converted_amount); - new_payments.push(EsdtTokenPayment::new( - universal_token_id, - 0, - converted_amount, - )); - } - - let caller = self.blockchain().get_caller(); - self.send().direct_multi(&caller, &new_payments); - - new_payments - } - - #[payable("*")] - #[endpoint(unwrapToken)] - fn unwrap_token(&self, requested_token: TokenIdentifier) { - require!(self.not_paused(), "Contract is paused"); - let (payment_token, payment_amount) = self.call_value().single_fungible_esdt(); - require!(payment_amount > 0u32, "Must pay more than 0 tokens!"); - - let universal_bridged_token_ids = self - .chain_specific_to_universal_mapping(&requested_token) - .get(); - require!( - payment_token == universal_bridged_token_ids, - "Esdt token unavailable" - ); - self.require_tokens_have_set_decimals_num(&payment_token, &requested_token); - - let chain_specific_token_id = &requested_token; - let converted_amount = self.get_converted_amount( - &payment_token, - chain_specific_token_id, - payment_amount.clone(), - ); - - self.token_liquidity(chain_specific_token_id).update(|liq| { - require!( - converted_amount <= *liq, - "Contract does not have enough funds" - ); - - *liq -= &converted_amount; - }); - - self.send() - .esdt_local_burn(&universal_bridged_token_ids, 0, &payment_amount); - - let caller = self.blockchain().get_caller(); - self.send() - .direct_esdt(&caller, chain_specific_token_id, 0, &converted_amount); - } - - fn get_converted_amount( - &self, - from: &TokenIdentifier, - to: &TokenIdentifier, - amount: BigUint, - ) -> BigUint { - let from_decimals = self.token_decimals_num(from).get(); - let to_decimals = self.token_decimals_num(to).get(); - let converted_amount = DFPBigUint::from_raw(amount, from_decimals); - converted_amount.convert(to_decimals).to_raw() - } - - fn require_mint_and_burn_roles(&self, token_id: &TokenIdentifier) { - let roles = self.blockchain().get_esdt_local_roles(token_id); - - require!( - roles.has_role(&EsdtLocalRole::Mint) && roles.has_role(&EsdtLocalRole::Burn), - "Must set local role first" - ); - } - - fn require_tokens_have_set_decimals_num( - &self, - universal_token: &TokenIdentifier, - chain_token: &TokenIdentifier, - ) { - require!( - !self.token_decimals_num(universal_token).is_empty(), - "Universal token requires updating" - ); - require!( - !self.token_decimals_num(chain_token).is_empty(), - "Chain-specific token requires updating" - ); - } - - #[view(getUniversalBridgedTokenIds)] - #[storage_mapper("universalBridgedTokenIds")] - fn universal_bridged_token_ids(&self) -> UnorderedSetMapper; - - #[view(getTokenLiquidity)] - #[storage_mapper("tokenLiquidity")] - fn token_liquidity(&self, token: &TokenIdentifier) -> SingleValueMapper; - - #[view(getChainSpecificToUniversalMapping)] - #[storage_mapper("chainSpecificToUniversalMapping")] - fn chain_specific_to_universal_mapping( - &self, - token: &TokenIdentifier, - ) -> SingleValueMapper; - - #[view(getchainSpecificTokenIds)] - #[storage_mapper("chainSpecificTokenIds")] - fn chain_specific_token_ids( - &self, - universal_token_id: &TokenIdentifier, - ) -> UnorderedSetMapper; - - #[storage_mapper("token_decimals_num")] - fn token_decimals_num(&self, token: &TokenIdentifier) -> SingleValueMapper; -} diff --git a/bridged-tokens-wrapper/testnet.toml b/bridged-tokens-wrapper/testnet.toml deleted file mode 100644 index e69de29b..00000000 diff --git a/bridged-tokens-wrapper/tests/dfp_big_uint_test.rs b/bridged-tokens-wrapper/tests/dfp_big_uint_test.rs deleted file mode 100644 index 31a2c9b5..00000000 --- a/bridged-tokens-wrapper/tests/dfp_big_uint_test.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![feature(associated_type_bounds)] -use bridged_tokens_wrapper::DFPBigUint; -use multiversx_sc_scenario::DebugApi; - -#[test] -fn test_biguint() { - let _ = DebugApi::dummy(); - let raw = 123456u64; - let dfp = DFPBigUint::::from_raw(raw.into(), 6); - let converted = dfp.clone().convert(9); - assert!(dfp.trunc() == converted.trunc()); - assert!(converted.clone().convert(9).to_raw() == 123456000u64); - assert!(converted.clone().convert(1).to_raw() == 1u64); - assert!(converted.clone().convert(3).to_raw() == 123u64); - assert!(converted.clone().convert(5).to_raw() == 12345u64); -} - -#[test] -fn test_mandos_scenario_values() { - let _ = DebugApi::dummy(); - let raw = 300000000000000u64; - let dfp = DFPBigUint::::from_raw(raw.into(), 18); - assert!(dfp.convert(6).to_raw() == 300u64); -} diff --git a/bridged-tokens-wrapper/wasm/Cargo.lock b/bridged-tokens-wrapper/wasm/Cargo.lock deleted file mode 100644 index b8c125ce..00000000 --- a/bridged-tokens-wrapper/wasm/Cargo.lock +++ /dev/null @@ -1,237 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "ahash" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", -] - -[[package]] -name = "arrayvec" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bridged-tokens-wrapper" -version = "0.0.0" -dependencies = [ - "multiversx-sc", - "multiversx-sc-modules", - "transaction", -] - -[[package]] -name = "bridged-tokens-wrapper-wasm" -version = "0.0.0" -dependencies = [ - "bridged-tokens-wrapper", - "multiversx-sc-wasm-adapter", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-literal" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" - -[[package]] -name = "multiversx-sc" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406939660d0c79dd191c6677f4b048df873a95f4531d8abafc9cdbe282bf1725" -dependencies = [ - "bitflags", - "hashbrown", - "hex-literal", - "multiversx-sc-codec", - "multiversx-sc-derive", - "num-traits", -] - -[[package]] -name = "multiversx-sc-codec" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" -dependencies = [ - "arrayvec", - "multiversx-sc-codec-derive", -] - -[[package]] -name = "multiversx-sc-codec-derive" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" -dependencies = [ - "hex", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "multiversx-sc-derive" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e006240993963b482fe0682ae49b2d07255495e3c86706925d119137376cdfc" -dependencies = [ - "hex", - "proc-macro2", - "quote", - "radix_trie", - "syn", -] - -[[package]] -name = "multiversx-sc-modules" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75dc2548fe5072cad37b5c816d2344d7cd12e8cafb1a0ff8bbf2bc1829054710" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "multiversx-sc-wasm-adapter" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40e721d1bc80de2ede4099a9040519486c3c1139cb0287d8fc4f9fc3e8a3f19e" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" - -[[package]] -name = "proc-macro2" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "transaction" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "unicode-ident" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/bridged-tokens-wrapper/wasm/Cargo.toml b/bridged-tokens-wrapper/wasm/Cargo.toml deleted file mode 100644 index b502021c..00000000 --- a/bridged-tokens-wrapper/wasm/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "bridged-tokens-wrapper-wasm" -version = "0.0.0" -authors = ["Alin Cruceat "] -edition = "2018" -publish = false - -[lib] -crate-type = ["cdylib"] -[profile.release] -codegen-units = 1 -opt-level = "z" -lto = true -debug = false -panic = "abort" -[dependencies.bridged-tokens-wrapper] -path = ".." - -[dependencies.multiversx-sc-wasm-adapter] -version = "0.43.4" - -[workspace] -members = ["."] diff --git a/bridged-tokens-wrapper/wasm/src/lib.rs b/bridged-tokens-wrapper/wasm/src/lib.rs deleted file mode 100644 index c59ba42a..00000000 --- a/bridged-tokens-wrapper/wasm/src/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. - -//////////////////////////////////////////////////// -////////////////// AUTO-GENERATED ////////////////// -//////////////////////////////////////////////////// - -// Init: 1 -// Endpoints: 17 -// Async Callback (empty): 1 -// Total number of exported functions: 19 - -#![no_std] - -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - -multiversx_sc_wasm_adapter::allocator!(); -multiversx_sc_wasm_adapter::panic_handler!(); - -multiversx_sc_wasm_adapter::endpoints! { - bridged_tokens_wrapper - ( - init => init - upgrade => upgrade - addWrappedToken => add_wrapped_token - updateWrappedToken => update_wrapped_token - removeWrappedToken => remove_wrapped_token - whitelistToken => whitelist_token - updateWhitelistedToken => update_whitelisted_token - blacklistToken => blacklist_token - depositLiquidity => deposit_liquidity - wrapTokens => wrap_tokens - unwrapToken => unwrap_token - getUniversalBridgedTokenIds => universal_bridged_token_ids - getTokenLiquidity => token_liquidity - getChainSpecificToUniversalMapping => chain_specific_to_universal_mapping - getchainSpecificTokenIds => chain_specific_token_ids - pause => pause_endpoint - unpause => unpause_endpoint - isPaused => paused_status - ) -} - -multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/esdt-safe/src/lib.rs b/esdt-safe/src/lib.rs index 22422f64..7d2e1355 100644 --- a/esdt-safe/src/lib.rs +++ b/esdt-safe/src/lib.rs @@ -24,9 +24,6 @@ pub trait EsdtSafe: + max_bridged_amount_module::MaxBridgedAmountModule + multiversx_sc_modules::pause::PauseModule { - /// fee_estimator_contract_address - The address of a Price Aggregator contract, - /// which will get the price of token A in token B - /// /// sovereign_tx_gas_limit - The gas limit that will be used for transactions on the Sovereign side. /// In case of SC gas limits, this value is provided by the user /// Will be used to compute the fees for the transfer diff --git a/multi-transfer-esdt/Cargo.toml b/multi-transfer-esdt/Cargo.toml index 1747eb34..27407ba3 100644 --- a/multi-transfer-esdt/Cargo.toml +++ b/multi-transfer-esdt/Cargo.toml @@ -17,9 +17,6 @@ path = "../common/tx-batch-module" [dependencies.max-bridged-amount-module] path = "../common/max-bridged-amount-module" -[dependencies.bridged-tokens-wrapper] -path = "../bridged-tokens-wrapper" - [dependencies.multiversx-sc] version = "0.43.4" diff --git a/multi-transfer-esdt/src/lib.rs b/multi-transfer-esdt/src/lib.rs index 2c2036fd..e3d0d482 100644 --- a/multi-transfer-esdt/src/lib.rs +++ b/multi-transfer-esdt/src/lib.rs @@ -15,14 +15,12 @@ pub trait MultiTransferEsdt: tx_batch_module::TxBatchModule + max_bridged_amount_module::MaxBridgedAmountModule { #[init] - fn init(&self, opt_wrapping_contract_address: OptionalValue) { + fn init(&self) { self.max_tx_batch_size() .set_if_empty(DEFAULT_MAX_TX_BATCH_SIZE); self.max_tx_batch_block_duration() .set_if_empty(DEFAULT_MAX_TX_BATCH_BLOCK_DURATION); - self.set_wrapping_contract_address(opt_wrapping_contract_address); - // batch ID 0 is considered invalid self.first_batch_id().set_if_empty(1); self.last_batch_id().set_if_empty(1); @@ -80,8 +78,7 @@ pub trait MultiTransferEsdt: valid_payments_list.push(user_tokens_to_send); } - let payments_after_wrapping = self.wrap_tokens(valid_payments_list); - self.distribute_payments(valid_dest_addresses_list, payments_after_wrapping); + self.distribute_payments(valid_dest_addresses_list, valid_payments_list); self.add_multiple_tx_to_batch(&refund_tx_list); } @@ -100,22 +97,6 @@ pub trait MultiTransferEsdt: opt_current_batch } - #[only_owner] - #[endpoint(setWrappingContractAddress)] - fn set_wrapping_contract_address(&self, opt_new_address: OptionalValue) { - match opt_new_address { - OptionalValue::Some(sc_addr) => { - require!( - self.blockchain().is_smart_contract(&sc_addr), - "Invalid unwrapping contract address" - ); - - self.wrapping_contract_address().set(&sc_addr); - } - OptionalValue::None => self.wrapping_contract_address().clear(), - } - } - // private fn check_must_refund( @@ -132,18 +113,10 @@ pub trait MultiTransferEsdt: return true; } - } else { - if !self.is_local_role_set(&token.token_identifier, &EsdtLocalRole::NftCreate) { - self.transfer_failed_invalid_token(batch_id, tx_nonce); - - return true; - } else if token.amount > NFT_AMOUNT - && !self.is_local_role_set(&token.token_identifier, &EsdtLocalRole::NftAddQuantity) - { - self.transfer_failed_invalid_token(batch_id, tx_nonce); + } else if !self.has_nft_roles(token) { + self.transfer_failed_invalid_token(batch_id, tx_nonce); - return true; - } + return true; } if self.is_above_max_amount(&token.token_identifier, &token.amount) { @@ -161,6 +134,20 @@ pub trait MultiTransferEsdt: false } + fn has_nft_roles(&self, payment: &EsdtTokenPayment) -> bool { + if !self.is_local_role_set(&payment.token_identifier, &EsdtLocalRole::NftCreate) { + return false; + } + + if payment.amount > NFT_AMOUNT + && !self.is_local_role_set(&payment.token_identifier, &EsdtLocalRole::NftAddQuantity) + { + return false; + } + + true + } + fn convert_to_refund_tx( &self, sov_tx: Transaction, @@ -243,29 +230,6 @@ pub trait MultiTransferEsdt: token_data.frozen } - fn wrap_tokens( - &self, - payments: ManagedVec>, - ) -> ManagedVec> { - if self.wrapping_contract_address().is_empty() { - return payments; - } - - // TODO: Think about making a single call here - let mut output_payments = ManagedVec::new(); - for user_payments in &payments { - let wrapped_payments: PaymentsVec = self - .get_wrapping_contract_proxy_instance() - .wrap_tokens() - .with_multi_token_transfer(user_payments) - .execute_on_dest_context(); - - output_payments.push(wrapped_payments); - } - - output_payments - } - fn distribute_payments( &self, dest_addresses: ManagedVec, @@ -276,24 +240,6 @@ pub trait MultiTransferEsdt: } } - // proxies - - #[proxy] - fn wrapping_contract_proxy( - &self, - sc_address: ManagedAddress, - ) -> bridged_tokens_wrapper::Proxy; - - fn get_wrapping_contract_proxy_instance(&self) -> bridged_tokens_wrapper::Proxy { - self.wrapping_contract_proxy(self.wrapping_contract_address().get()) - } - - // storage - - #[view(getWrappingContractAddress)] - #[storage_mapper("wrappingContractAddress")] - fn wrapping_contract_address(&self) -> SingleValueMapper; - // events #[event("transferPerformedEvent")] diff --git a/multisig/.gitignore b/multisig/.gitignore deleted file mode 100644 index 9494cb14..00000000 --- a/multisig/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ -*/target/ - -# The mxpy output -output diff --git a/multisig/Cargo.toml b/multisig/Cargo.toml deleted file mode 100644 index 4ce33880..00000000 --- a/multisig/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "multisig" -version = "0.0.0" -authors = ["Andrei Marinica , Dorin Iancu "] -edition = "2018" -publish = false - -[lib] -path = "src/lib.rs" - -[dependencies.transaction] -path = "../common/transaction" - -[dependencies.token-module] -path = "../common/token-module" - -[dependencies.tx-batch-module] -path = "../common/tx-batch-module" - -[dependencies.max-bridged-amount-module] -path = "../common/max-bridged-amount-module" - -[dependencies.esdt-safe] -path = "../esdt-safe" - -[dependencies.multi-transfer-esdt] -path = "../multi-transfer-esdt" - -[dependencies.multiversx-sc] -version = "0.43.4" - -[dependencies.multiversx-sc-modules] -version = "0.43.4" - -[dev-dependencies.multiversx-sc-scenario] -version = "0.43.4" diff --git a/multisig/README.md b/multisig/README.md deleted file mode 100644 index 8f0b223f..00000000 --- a/multisig/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# Multisig Smart Contract (MSC) - -## Abstract -Cryptocurrencies can be one of the safest ways to store and manage wealth and value. By safeguarding a short list of words, the so-called seed or recovery phrase, anyone can protect thousands or millions of dollars in wealth and rest assured that no hacker or government can take it from them. In practice, it’s never so easy. - -One problem is that single-signature addresses rely on protecting a single private key. - -A better solution would use for example 2-of-3 multisig (or any combination of M-of-N for M ≤ N) quorum consisting of three separate private keys, held by three separate people or entities, and requiring any two to sign. This provides both security and redundancy since compromising any one key/person does not break the quorum: if one key is stolen or lost, the other two keyholders can sweep funds to another address (protected by a new quorum) by mutually signing a transaction moving the funds. - -As an example, let us imagine the following scenario. An institution launches a stablecoin. For safety, it is required that 3 out of 5 designated addresses sign any mint or burn transaction. Alice deploys the multisig SC. She adds Bob, Charlie, Dave and Eve as signers to the contract and sets the quorum to a minimum number of signers to 3. A quorum of signatures is also required to add or remove signers after the initial deployment. If for some reason, Eve’s account is compromised, Alice proposes removing Eve’s address from the signers’ board. Charlie and Dave sign, causing Eve’s address to be removed. There are only 4 addresses now registered in the contract. By the same process, signers could add 2 more addresses to their ranks, and increase the required quorum signatures from 3 to 4. - -Thus, essentially the multisig SC (we will refer to it, from now on, as MSC) enables multiple parties to sign or approve an action that takes place - typically a requirement for certain wallets, accounts, and smart contracts to prevent a rogue or hacked individual from performing detrimental actions. - -## Multisig transaction flow -On-chain multisig wallets are made possible by the fact that smart contracts can call other smart contracts. To execute a multisig transaction the flow would be: - -* A proposer or board member proposes an action. -* The proposed action receives an unique id/hash. -* N board members are notified (off-chain) to review the action with the specific id/hash. -* M out of N board members sign and approve the action. -* Any proposer or board member “performs the action”. - -## Design guidelines - -The required guidelines are: -* **No external contracts.** Calling methods of other contracts from within the methods of your own MSC is an amazing feature but should not be required for our simple use case. This also avoids exposing us to bugs. Because any arbitrarily complex function call can be executed, the MSC functions exactly as a standard wallet, but requires multiple signatures. - -* **No libraries.** Extending the last guideline, our contract has no upstream dependencies other than itself. This minimizes the chance of us misunderstanding or misusing some piece of library code. It also forces us to stay simple and eases auditing and eventually formal verification. - -* **Minimal internal state.** Complex applications can be built inside Elrond smart contracts. Storing minimal internal state allows our contract’s code to be simpler, and to be written in a more functional style, which is easier to test and reason about. - -* **Uses cold-storage.** The proposer which creates an action or spends from the contract has no special rights or access to the MSC. Authorization is handled by directly signing messages by the board members’ wallets that can be hardware wallets (Trezor; Ledger, etc.) or software wallets. - -* **Complete end-to-end testing.** The contract itself is exhaustively unit tested, audited and formally verified. - -## Roles -* **Deployer** - This is the address that deploys the MSC. By default, this address is also the owner of the SC, but the owner can be changed later if required, as this is by default supported by the Elrond protocol itself. This is the address that initially set up the configuration of the SC: board members, quorum, etc. It is important to mention that at deployment a very important configuration parameter is the option to allow the SC to be upgradeable or not. It is recommended for most use cases the SC to be non-upgradeable. Leaving the SC upgradable will give the owner of the SC the possibility to upgrade the SC and bypass the board, defeating the purpose of a MSC. If keeping the SC upgradeable is desired, a possible approach would be to make the owner another MSC, and both SCs could maintain the same board, so an upgrade action would need the approval of the board. - -* **Owner** - The deployer is initially the owner of the MSC, but if desired can be changed later by the current owner to a different owner. If the SC is upgradeable, the owner can also upgrade the SC. - -* **Board and quorum** - Multiple addresses need to be previously registered in the MSC, forming its board. A board member needs to be specifically registered as a board member, meaning for example that the owner or deployer of the MSC is not automatically a board member as well. Board members can vote on every action that the MSC performs. Signing a proposed action means the board members agree. Customarily, not all board members will need to sign every action; the MSC will configure how many signatures will be necessary for an action to be performed, the quorum. For instance, such a contract could have 5 board members, but a quorum of 3 would be enough to perform any action (M-of-N or in this case 3-of-5). - -* **Proposer** - The proposer is an address whitelisted in the MSC that can propose any action. An action can be any transaction; for example: send 10 eGLD to the treasury, mint more ESDT, etc. All board members are proposers by default but non-board members can be added as well to the list of whitelisted proposers. The proposers can only propose actions that then need to be approved and signed by the board members. The board member that proposes an action doesn’t need to sign it anymore; it is considered signed. - -## Functionality -The MSC should be able to perform most tasks that a regular account is able to perform. It should also be as general as possible. This means that it should operate with a generic concept of “Action”, that the board needs to sign before being performed. Actions can interact with the MSC itself (let's call them **internal actions**) or with external addresses or other SC (**external actions**). - -External actions have one and only one function, which is to send the action as a transaction whose sender is the MSC. Because any arbitrarily complex function call can be executed, the MSC functions exactly as a standard wallet, but requires multiple signatures. - -The types of internal actions should be the following: - -* Add a new member to the board. -* Remove a member from the board. This is only allowed if the new board size remains larger than the number of required signatures (quorum). Otherwise, a new member needs to be added first. -* Change the quorum: the required number of signatures. Restriction: 1 <= quorum <= board size. -* Add a proposer. -* Remove a proposer. -* Change multisig contract owner (might be relevant for upgrading the MSC). -* Pay functions - by default we recommend the MSC to not be set up as a payable SC and any deposit or send transaction of eGLD or ESDT towards the MSC will need to call the desired pay function (if a transaction is not a call to these 2 functions then it is rejected immediately and the value is sent back to original sender): Deposit and/or Send. By making the MSC not a payable MSC we reduce the risk of users sending into the MSC funds that then are locked in the MSC or need to be manually send back to the user (in case of a mistake). By making the MSC not a payable MSC it also means that any deposit or send transaction needs to explicitly call the deposit or send function of the MSC. - -Any external and internal action will follow these steps and process: - -* **Propose action:** this will generate an action id. The action id is unique. -* **View action:** the board members need to see the action proposed before they approve it. -* **Sign action:** board members are allowed to sign. We might add an expiration date until board members can sign (until block x…). -* **Un-sign action:** board members are allowed to un-sign, i.e. to remove their signature from an action. Actions with 0 signatures are cleared from storage. This is to allow mistakes to be cleared. -* **Perform action (by id/hash)** - can be activated by proposers or board members. It is successful only if enough signatures are present from the board members. Whoever calls “perform action” needs to provide any eGLD required by the target, as well as to pay for gas. If there is a move balance kind of action, who calls the action pays the gas and the amount to be moved is taken from MSC balance. But the gas is always taken from the balance of the one who creates the "perform action" transaction. - -Also, the following view functions will be available: -* **Count pending Actions:** returns the number of existing Actions. -* **List latest N pending Actions:** provides hashes of the latest N pending Actions, most recent being 0 and oldest being N-1. Usually called in tandem with Count. - -## Initializing the MSC - -There are 2 ways to do it: -* Provide all board member addresses and the number of required signatures directly in the constructor. -* Deployer deploys with just herself on the board and required signatures = 1. Then adds all other N-1 signers and sets required signatures to M. This works, but requires many transactions, so the constructor-only approach might be preferred. - -MSC is a deployable SC written in Rust and compiled in WASM. - -## Conclusion - -Multisig accounts are a critical safety feature for all users of the Elrond ecosystem. Decentralised applications will rely heavily upon multisig security. diff --git a/multisig/interaction/README.md b/multisig/interaction/README.md deleted file mode 100644 index 54d72848..00000000 --- a/multisig/interaction/README.md +++ /dev/null @@ -1,22 +0,0 @@ -## Using snippets script for the bridge SCs - -### Step 1: Update [configs.cfg](config/configs.cfg) -- Update Alice(owner) and initial relayers' pem location. -- Update any other SC setting that you would like to change. - -### Step 2: Run script file: -Run script.sh with a given command. -Available commands are: -- deploy-aggregator -- deploy-wrapper -- deploy-bridge-contracts -- add-relayer -- remove-relayer -- whitelist-token -- set-safe-max-tx -- set-safe-batch-block-duration -- change-quorum -- pause-contracts -- unpause-contracts - -All the commands that are changing any SC settings will automatically update also [configs.cfg](config/configs.cfg). However, there are some points (like token issueing) when the admin will be ask to first update the configs before proceeding with next steps. \ No newline at end of file diff --git a/multisig/interaction/config/aggregator-snippets.sh b/multisig/interaction/config/aggregator-snippets.sh deleted file mode 100644 index 3c12fa92..00000000 --- a/multisig/interaction/config/aggregator-snippets.sh +++ /dev/null @@ -1,43 +0,0 @@ -deployAggregator() { - CHECK_VARIABLES AGGREGATOR_WASM CHAIN_SPECIFIC_TOKEN ALICE_ADDRESS - - mxpy --verbose contract deploy --bytecode=${AGGREGATOR_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=100000000 --arguments 1 0 ${ALICE_ADDRESS} \ - --send --outfile=deploy-price-agregator-testnet.interaction.json --proxy=${PROXY} --chain=${CHAIN_ID} || return - - TRANSACTION=$(mxpy data parse --file="./deploy-price-agregator-testnet.interaction.json" --expression="data['emittedTransactionHash']") - ADDRESS=$(mxpy data parse --file="./deploy-price-agregator-testnet.interaction.json" --expression="data['contractAddress']") - - mxpy data store --key=address-testnet-safe --value=${ADDRESS} - mxpy data store --key=deployTransaction-testnet --value=${TRANSACTION} - - echo "" - echo "Price agregator: ${ADDRESS}" -} - -submitAggregatorBatch() { - CHECK_VARIABLES AGGREGATOR CHAIN_SPECIFIC_TOKEN FEE_AMOUNT NR_DECIMALS_CHAIN_SPECIFIC - - FEE=$(echo "scale=0; $FEE_AMOUNT*10^$NR_DECIMALS_CHAIN_SPECIFIC/1" | bc) - - mxpy --verbose contract call ${AGGREGATOR} --recall-nonce --pem=${ALICE} \ - --gas-limit=15000000 --function="submitBatch" \ - --arguments str:GWEI str:${CHAIN_SPECIFIC_TOKEN_TICKER} ${FEE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} || return -} - -pauseAggregator() { - CHECK_VARIABLES AGGREGATOR - - mxpy --verbose contract call ${AGGREGATOR} --recall-nonce --pem=${ALICE} \ - --gas-limit=5000000 --function="pause" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} || return -} - -unpauseAggregator() { - CHECK_VARIABLES AGGREGATOR - - mxpy --verbose contract call ${AGGREGATOR} --recall-nonce --pem=${ALICE} \ - --gas-limit=5000000 --function="unpause" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} || return -} diff --git a/multisig/interaction/config/configs.cfg b/multisig/interaction/config/configs.cfg deleted file mode 100644 index 9b58c555..00000000 --- a/multisig/interaction/config/configs.cfg +++ /dev/null @@ -1,79 +0,0 @@ -ESDT_SYSTEM_SC_ADDRESS=erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u - -#============CHAIN============== - -PROXY=https://testnet-gateway.multiversx.com -CHAIN_ID=T - -#============OWNER============== - -ALICE="./wallets/erd1zsha9cvx7gwraytgp740dcjzwy9v5xwnmas77d33uve6sk0rs0vqel4ln5.pem" -ALICE_ADDRESS=erd1zsha9cvx7gwraytgp740dcjzwy9v5xwnmas77d33uve6sk0rs0vqel4ln5 - -#============WASM FILES============== - -AGGREGATOR_WASM="./price-aggregator.wasm" -SAFE_WASM="./esdt-safe.wasm" -BRIDGED_TOKENS_WRAPPER_WASM="./bridged-tokens-wrapper.wasm" -MULTI_TRANSFER_WASM="./multi-transfer-esdt.wasm" -MULTISIG_WASM="./multisig.wasm" - -#============CONTRACT ADDRESSES============== - -AGGREGATOR=erd1qqqqqqqqqqqqqpgqnlxmcs47kunkewcllqh0d72gv5pjhvfvs0vqa57fhf -SAFE=erd1qqqqqqqqqqqqqpgqkhx64czgpc84eftg6q25lrfyv95ndwtcs0vqwusfuh -BRIDGED_TOKENS_WRAPPER=erd1qqqqqqqqqqqqqpgqlgjwk8mpfycxpdf9q2sgzcndtdhdxr5ss0vqgygjmn -MULTI_TRANSFER=erd1qqqqqqqqqqqqqpgqjsh8kss3w67xks7ths5d795q3nz8y52as0vqu0ujzg -MULTISIG=erd1qqqqqqqqqqqqqpgqdcat402y6c62hv07gt04rynjg4668z9fs0vq3qxepp - -#============TOKENS SETTINGS============== -NR_DECIMALS_CHAIN_SPECIFIC=6 -NR_DECIMALS_UNIVERSAL=6 - -UNIVERSAL_TOKEN_TICKER=USDC -UNIVERSAL_TOKEN_DISPLAY_NAME=WrappedUSDC - -CHAIN_SPECIFIC_TOKEN_TICKER=ETHUSDC -CHAIN_SPECIFIC_TOKEN_DISPLAY_NAME=EthereumWrappedUSDC -UNIVERSAL_TOKENS_ALREADY_MINTED=0 - -#============TOKENS TO BE WHITELISTED============== -UNIVERSAL_TOKEN=USDT-92ae4e -CHAIN_SPECIFIC_TOKEN=ETHUSDT-41b065 -ERC20_TOKEN=0xbe388e5276035575e672ce795a87d16976ecaacb - -#============BRIDGE SETTINGS============== - -FEE_AMOUNT=50 # value without decimals -MAX_AMOUNT=100000 # value without decimals - -RELAYER_REQUIRED_STAKE=0 #1000eGLD -SLASH_AMOUNT=0 -QUORUM=3 - -MAX_TX_PER_BATCH=70 -MAX_TX_BLOCK_DURATION_PER_BATCH=100 #10minutes - -#============RELAYERS ADDRESSES============== -RELAYER_ADDR_0=erd1l9hpewk3dd6mz5j0yytjnzqtydukslmsms2d0fn0pg8pc42chqgqk8pm5u -RELAYER_ADDR_1=erd1tfj6fpr5hd5fw8h6efycw42mk3c4wynausntvg6x98kcyn5npkkqmq7t9g -RELAYER_ADDR_2=erd1689ky73s93aptw8ek0wrrzujtus365ygrqgj0hgj4cn09n5k3kuqyhr0j7 -RELAYER_ADDR_3=erd1uae36y2qvrslexcv3mwjqy9lwrlspvkdyjsar2xcj5ctrq7th26q8twvyc -RELAYER_ADDR_4=erd1pkwhtl85ze02ckaf0t6qgycgx863kxyefxyqxumcth0nwtu3a9yqzg2yn2 -RELAYER_ADDR_5=erd197rmyux8ttzuwssh9thsewlzsc766tvpnussqkpew5vm9x63k0kqw56hr7 -RELAYER_ADDR_6=erd1yhqfhsf237uyz4uzzg0duy9hhg8t3j4wtt020c5cy59w2v2jvkgq6nxf0c -RELAYER_ADDR_7=erd1pgvt06tyhlwegkdkzknyhcxfl3wz69wseqeqashm3d83mxjaewzqnug90w -RELAYER_ADDR_8=erd1ujfl0yxff6ey008ef89au4dn486dj549kpjuuu4xxtn9q550x3gqcu6wed -RELAYER_ADDR_9=erd1zsha9cvx7gwraytgp740dcjzwy9v5xwnmas77d33uve6sk0rs0vqel4ln5 - -RELAYER_WALLET0="./walletsRelay/${RELAYER_ADDR_0}.pem" -RELAYER_WALLET1="./walletsRelay/${RELAYER_ADDR_1}.pem" -RELAYER_WALLET2="./walletsRelay/${RELAYER_ADDR_2}.pem" -RELAYER_WALLET3="./walletsRelay/${RELAYER_ADDR_3}.pem" -RELAYER_WALLET4="./walletsRelay/${RELAYER_ADDR_4}.pem" -RELAYER_WALLET5="./walletsRelay/${RELAYER_ADDR_5}.pem" -RELAYER_WALLET6="./walletsRelay/${RELAYER_ADDR_6}.pem" -RELAYER_WALLET7="./walletsRelay/${RELAYER_ADDR_7}.pem" -RELAYER_WALLET8="./walletsRelay/${RELAYER_ADDR_8}.pem" -RELAYER_WALLET9="./walletsRelay/${RELAYER_ADDR_9}.pem" - diff --git a/multisig/interaction/config/helper.cfg b/multisig/interaction/config/helper.cfg deleted file mode 100644 index 0d8d105e..00000000 --- a/multisig/interaction/config/helper.cfg +++ /dev/null @@ -1,74 +0,0 @@ -CONFIG_FILE=$SCRIPTPATH/config/configs.cfg -function confirmation { - FUNC="$1" - echo -e - read -p "Do you want to go on with ${GREEN}"${FUNC}"${NC} (Default No) ? (Yy/Nn)" yn - echo -e - - case $yn in - [Yy]* ) - - echo -e "${GREEN}Proceeding with "${FUNC}"!${NC}" - ${FUNC} - ;; - [Nn]* ) - echo -e "${GREEN}Exiting...${NC}" - ;; - - * ) - echo -e "${GREEN}I'll take that as a no then... ${NC}" - ;; - esac -} - -function confirmation-with-skip { - FUNC="$1" - echo -e - read -p "Do you want to go on with "${FUNC}" (Default No) ? (Yy/Nn)" yn - echo -e - - case $yn in - [Yy]* ) - - echo -e "${GREEN}Proceeding with "${FUNC}"!${NC}" - ${FUNC} - ;; - [Nn]* ) - ;; - - * ) - echo -e "${GREEN}I'll take that as a no then... ${NC}" - ;; - esac -} - -function continue-confirmation { - FUNC="$1" - echo -e - read -p "Enter any key to continue with "${FUNC}"" yn - echo -e - - ${FUNC} -} - -function manual-update-config-file { - source $SCRIPTPATH/config/configs.cfg -} - -function update-config { - TARGET_KEY=$1 - REPLACEMENT_VALUE=$2 - sed "s/^$TARGET_KEY=.*/$TARGET_KEY=$REPLACEMENT_VALUE/" $CONFIG_FILE > $SCRIPTPATH/config/temp.x - mv $SCRIPTPATH/config/temp.x "$CONFIG_FILE" - source $CONFIG_FILE -} - -CHECK_VARIABLES() -{ - VARIABLE_NAMES=("$@") - for VARIABLE_NAME in "${VARIABLE_NAMES[@]}"; do - [ -z "${!VARIABLE_NAME}" ] && echo "$VARIABLE_NAME variable is unset." && VAR_UNSET=true - done - [ -n "$VAR_UNSET" ] && return 1 - return 0 -} \ No newline at end of file diff --git a/multisig/interaction/config/issue-tokens-snippets.sh b/multisig/interaction/config/issue-tokens-snippets.sh deleted file mode 100644 index b800bcde..00000000 --- a/multisig/interaction/config/issue-tokens-snippets.sh +++ /dev/null @@ -1,60 +0,0 @@ -ESDT_ISSUE_COST=50000000000000000 - -issueUniversalToken() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS ESDT_ISSUE_COST UNIVERSAL_TOKEN_DISPLAY_NAME \ - UNIVERSAL_TOKEN_TICKER NR_DECIMALS_UNIVERSAL - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --value=${ESDT_ISSUE_COST} --function="issue" \ - --arguments str:${UNIVERSAL_TOKEN_DISPLAY_NAME} str:${UNIVERSAL_TOKEN_TICKER} \ - 0 ${NR_DECIMALS_UNIVERSAL} str:canAddSpecialRoles str:true \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -issueChainSpecificToken() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS ESDT_ISSUE_COST CHAIN_SPECIFIC_TOKEN_DISPLAY_NAME \ - CHAIN_SPECIFIC_TOKEN_TICKER NR_DECIMALS_CHAIN_SPECIFIC UNIVERSAL_TOKENS_ALREADY_MINTED - - VALUE_TO_MINT=$(echo "scale=0; $UNIVERSAL_TOKENS_ALREADY_MINTED*10^$NR_DECIMALS_CHAIN_SPECIFIC/1" | bc) - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --value=${ESDT_ISSUE_COST} --function="issue" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN_DISPLAY_NAME} str:${CHAIN_SPECIFIC_TOKEN_TICKER} \ - ${VALUE_TO_MINT} ${NR_DECIMALS_CHAIN_SPECIFIC} str:canAddSpecialRoles str:true \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -transferToSC() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER CHAIN_SPECIFIC_TOKEN - - VALUE_TO_MINT=$(echo "scale=0; $UNIVERSAL_TOKENS_ALREADY_MINTED*10^$NR_DECIMALS_CHAIN_SPECIFIC/1" | bc) - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=5000000 --function="ESDTTransfer" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${VALUE_TO_MINT} str:depositLiquidity \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -setMintRole() { - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="setSpecialRole" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${ALICE_ADDRESS} str:ESDTRoleLocalMint \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -unSetMintRole() { - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="unSetSpecialRole" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${ALICE_ADDRESS} str:ESDTRoleLocalMint \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -mint() { - CHECK_VARIABLES NR_DECIMALS_CHAIN_SPECIFIC ALICE_ADDRESS CHAIN_SPECIFIC_TOKEN - read -p "Amount to mint(without decimals): " AMOUNT_TO_MINT - VALUE_TO_MINT=$(echo "scale=0; $AMOUNT_TO_MINT*10^$NR_DECIMALS_CHAIN_SPECIFIC/1" | bc) - mxpy --verbose contract call ${ALICE_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=300000 --function="ESDTLocalMint" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${VALUE_TO_MINT} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} \ No newline at end of file diff --git a/multisig/interaction/config/menu_functions.cfg b/multisig/interaction/config/menu_functions.cfg deleted file mode 100644 index e7585ccf..00000000 --- a/multisig/interaction/config/menu_functions.cfg +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/bash -set -e - -source $SCRIPTPATH/config/aggregator-snippets.sh -source $SCRIPTPATH/config/issue-tokens-snippets.sh -source $SCRIPTPATH/config/multisig-snippets.sh -source $SCRIPTPATH/config/multitransfer-snippets.sh -source $SCRIPTPATH/config/relayers-snippets.sh -source $SCRIPTPATH/config/upgrade-snippets.sh -source $SCRIPTPATH/config/wrapped-snippets.sh -source $SCRIPTPATH/config/safe-snippets.sh - -CHECK_VARIABLES ALICE PROXY CHAIN_ID -function deploy-aggregator { - deployAggregator - update-config AGGREGATOR ${ADDRESS} - confirmation-with-skip unpauseAggregator - - echo -e - echo "Aggregator deployed!" - echo -e -} - -function deploy-wrapper { - deployBridgedTokensWrapper - update-config BRIDGED_TOKENS_WRAPPER ${ADDRESS} -} - -function upgrade-wrapper { - wrapper-upgrade -} - -function upgrade-wrapper-universal-token { - wrapper-updateWrappedToken -} - -function upgrade-wrapper-chain-specific-token { - wrapper-updateWhitelistedToken -} - -function deploy-bridge-contracts { - deploySafe - update-config SAFE ${ADDRESS} - confirmation-with-skip deployMultiTransfer - update-config MULTI_TRANSFER ${ADDRESS} - confirmation-with-skip deployMultisig - update-config MULTISIG ${ADDRESS} - confirmation-with-skip changeChildContractsOwnershipSafe - confirmation-with-skip changeChildContractsOwnershipMultiTransfer -} - -function remove-whitelist-token { - echo -e - echo "Update TOKENS TO BE WHITELISTED section in configs.cfg with the SC" - echo -e - confirmation-with-skip manual-update-config-file - confirmation-with-skip unsetLocalRolesBridgedTokensWrapper - - confirmation-with-skip removeWrappedToken - confirmation-with-skip wrapper-blacklistToken - confirmation-with-skip unsetLocalRolesEsdtSafe - confirmation-with-skip unsetLocalRolesMultiTransferEsdt - confirmation-with-skip clearMapping - confirmation-with-skip removeTokenFromWhitelist -} - -function whitelist-token { - echo -e - echo "PREREQUIREMENTS: BRIDGED_TOKENS_WRAPPER needs to have MINT+BURN role for the UNIVERSAL TOKEN" - echo "Check and update TOKENS SETTINGS section in configs.cfg" - echo -e - confirmation-with-skip manual-update-config-file - - confirmation-with-skip issueUniversalToken - confirmation-with-skip issueChainSpecificToken - - echo -e - echo "Update TOKENS TO BE WHITELISTED section in configs.cfg with the SC" - echo -e - confirmation-with-skip manual-update-config-file - confirmation-with-skip setLocalRolesBridgedTokensWrapper - - confirmation-with-skip transferToSC - confirmation-with-skip addWrappedToken - confirmation-with-skip wrapper-whitelistToken - confirmation-with-skip setLocalRolesEsdtSafe - confirmation-with-skip setLocalRolesMultiTransferEsdt - confirmation-with-skip addMapping - confirmation-with-skip addTokenToWhitelist - echo -e - echo "Update FEE_AMOUNT and MAX_AMOUNT in BRIDGE SETTINGS section in configs.cfg" - echo -e - confirmation-with-skip manual-update-config-file - - confirmation-with-skip submitAggregatorBatch - - confirmation-with-skip esdtSafeSetMaxBridgedAmountForToken - confirmation-with-skip multiTransferEsdtSetMaxBridgedAmountForToken -} - -function change-quorum { - read -p "Quorum: " QUORUM - update-config QUORUM ${QUORUM} - changeQuorum -} - -function set-safe-max-tx { - read -p "New batch size: " BATCH_SIZE - update-config MAX_TX_PER_BATCH ${BATCH_SIZE} - esdtSafeSetMaxTxBatchSize -} - -function set-safe-batch-block-duration { - read -p "New batch block duration: " BLOCK_DURATION - update-config MAX_TX_BLOCK_DURATION_PER_BATCH ${BLOCK_DURATION} - esdtSafeSetMaxTxBatchBlockDuration -} - -function pause-contracts { - confirmation-with-skip pause - confirmation-with-skip pauseEsdtSafe - confirmation-with-skip pauseAggregator - confirmation-with-skip wrapper-pause -} - -function unpause-contracts { - confirmation-with-skip unpause - confirmation-with-skip unpauseEsdtSafe - confirmation-with-skip unpauseAggregator - confirmation-with-skip wrapper-unpause -} - -function set-fee { - confirmation-with-skip submitAggregatorBatch -} - -function mint-chain-specific { - confirmation-with-skip setMintRole - confirmation-with-skip mint - update-config UNIVERSAL_TOKENS_ALREADY_MINTED ${AMOUNT_TO_MINT} - confirmation-with-skip transferToSC - confirmation-with-skip unSetMintRole -} \ No newline at end of file diff --git a/multisig/interaction/config/multisig-snippets.sh b/multisig/interaction/config/multisig-snippets.sh deleted file mode 100644 index 2037bfc1..00000000 --- a/multisig/interaction/config/multisig-snippets.sh +++ /dev/null @@ -1,164 +0,0 @@ -deployMultisig() { - CHECK_VARIABLES RELAYER_ADDR_0 RELAYER_ADDR_1 RELAYER_ADDR_2 RELAYER_ADDR_3 \ - RELAYER_ADDR_4 RELAYER_ADDR_5 RELAYER_ADDR_6 RELAYER_ADDR_7 RELAYER_ADDR_8 \ - RELAYER_ADDR_9 SAFE MULTI_TRANSFER RELAYER_REQUIRED_STAKE SLASH_AMOUNT QUORUM MULTISIG_WASM - - MIN_STAKE=$(echo "$RELAYER_REQUIRED_STAKE*10^18" | bc) - mxpy --verbose contract deploy --bytecode=${MULTISIG_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=200000000 \ - --arguments ${SAFE} ${MULTI_TRANSFER} \ - ${MIN_STAKE} ${SLASH_AMOUNT} ${QUORUM} \ - ${RELAYER_ADDR_0} ${RELAYER_ADDR_1} ${RELAYER_ADDR_2} ${RELAYER_ADDR_3} \ - --send --outfile="deploy-testnet.interaction.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return - - TRANSACTION=$(mxpy data parse --file="./deploy-testnet.interaction.json" --expression="data['emitted_tx']['hash']") - ADDRESS=$(mxpy data parse --file="./deploy-testnet.interaction.json" --expression="data['contractAddress']") - - mxpy data store --key=address-testnet-multisig --value=${ADDRESS} - mxpy data store --key=deployTransaction-testnet --value=${TRANSACTION} - - echo "" - echo "Multisig contract address: ${ADDRESS}" -} - -changeChildContractsOwnershipSafe() { - CHECK_VARIABLES SAFE MULTISIG - - mxpy --verbose contract call ${SAFE} --recall-nonce --pem=${ALICE} \ - --gas-limit=10000000 --function="ChangeOwnerAddress" \ - --arguments ${MULTISIG} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -changeChildContractsOwnershipMultiTransfer() { - CHECK_VARIABLES MULTI_TRANSFER MULTISIG - - mxpy --verbose contract call ${MULTI_TRANSFER} --recall-nonce --pem=${ALICE} \ - --gas-limit=10000000 --function="ChangeOwnerAddress" \ - --arguments ${MULTISIG} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -clearMapping() { - CHECK_VARIABLES ERC20_TOKEN CHAIN_SPECIFIC_TOKEN MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="clearMapping" \ - --arguments ${ERC20_TOKEN} str:${CHAIN_SPECIFIC_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -addMapping() { - CHECK_VARIABLES ERC20_TOKEN CHAIN_SPECIFIC_TOKEN MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="addMapping" \ - --arguments ${ERC20_TOKEN} str:${CHAIN_SPECIFIC_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -addTokenToWhitelist() { - CHECK_VARIABLES CHAIN_SPECIFIC_TOKEN CHAIN_SPECIFIC_TOKEN_TICKER MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="esdtSafeAddTokenToWhitelist" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} str:${CHAIN_SPECIFIC_TOKEN_TICKER} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -removeTokenFromWhitelist() { - CHECK_VARIABLES CHAIN_SPECIFIC_TOKEN CHAIN_SPECIFIC_TOKEN_TICKER MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="esdtSafeRemoveTokenFromWhitelist" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -esdtSafeSetMaxTxBatchSize() { - CHECK_VARIABLES MAX_TX_PER_BATCH MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=30000000 --function="esdtSafeSetMaxTxBatchSize" \ - --arguments ${MAX_TX_PER_BATCH} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -esdtSafeSetMaxTxBatchBlockDuration() { - CHECK_VARIABLES MAX_TX_BLOCK_DURATION_PER_BATCH MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=30000000 --function="esdtSafeSetMaxTxBatchBlockDuration" \ - --arguments ${MAX_TX_BLOCK_DURATION_PER_BATCH} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -clearMapping() { - CHECK_VARIABLES ERC20_TOKEN CHAIN_SPECIFIC_TOKEN MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="clearMapping" \ - --arguments ${ERC20_TOKEN} str:${CHAIN_SPECIFIC_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -changeQuorum() { - CHECK_VARIABLES QUORUM MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="changeQuorum" \ - --arguments ${QUORUM} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -pause() { - CHECK_VARIABLES MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="pause" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -pauseEsdtSafe() { - CHECK_VARIABLES MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="pauseEsdtSafe" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -unpause() { - CHECK_VARIABLES MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="unpause" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -unpauseEsdtSafe() { - CHECK_VARIABLES MULTISIG - - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="unpauseEsdtSafe" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -esdtSafeSetMaxBridgedAmountForToken() { - CHECK_VARIABLES MAX_AMOUNT NR_DECIMALS_CHAIN_SPECIFIC CHAIN_SPECIFIC_TOKEN MULTISIG - - MAX=$(echo "scale=0; $MAX_AMOUNT*10^$NR_DECIMALS_CHAIN_SPECIFIC/1" | bc) - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="esdtSafeSetMaxBridgedAmountForToken" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${MAX} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -multiTransferEsdtSetMaxBridgedAmountForToken() { - CHECK_VARIABLES MAX_AMOUNT NR_DECIMALS_CHAIN_SPECIFIC CHAIN_SPECIFIC_TOKEN MULTISIG - - MAX=$(echo "scale=0; $MAX_AMOUNT*10^$NR_DECIMALS_CHAIN_SPECIFIC/1" | bc) - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=40000000 --function="multiTransferEsdtSetMaxBridgedAmountForToken" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${MAX} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} diff --git a/multisig/interaction/config/multitransfer-snippets.sh b/multisig/interaction/config/multitransfer-snippets.sh deleted file mode 100644 index 38304735..00000000 --- a/multisig/interaction/config/multitransfer-snippets.sh +++ /dev/null @@ -1,32 +0,0 @@ -deployMultiTransfer() { - CHECK_VARIABLES MULTI_TRANSFER_WASM BRIDGED_TOKENS_WRAPPER - - mxpy --verbose contract deploy --bytecode=${MULTI_TRANSFER_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=100000000 \ - --arguments ${BRIDGED_TOKENS_WRAPPER} --metadata-payable \ - --send --outfile="deploy-multitransfer-testnet.interaction.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return - - ADDRESS=$(mxpy data parse --file="./deploy-multitransfer-testnet.interaction.json" --expression="data['contractAddress']") - mxpy data store --key=address-testnet-multitransfer --value=${ADDRESS} - - echo "" - echo "Multi transfer contract address: ${ADDRESS}" -} - -setLocalRolesMultiTransferEsdt() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS CHAIN_SPECIFIC_TOKEN MULTI_TRANSFER - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="setSpecialRole" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${MULTI_TRANSFER} str:ESDTRoleLocalMint \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -unsetLocalRolesMultiTransferEsdt() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS CHAIN_SPECIFIC_TOKEN MULTI_TRANSFER - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="unSetSpecialRole" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${MULTI_TRANSFER} str:ESDTRoleLocalMint \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} \ No newline at end of file diff --git a/multisig/interaction/config/relayers-snippets.sh b/multisig/interaction/config/relayers-snippets.sh deleted file mode 100644 index 3528a641..00000000 --- a/multisig/interaction/config/relayers-snippets.sh +++ /dev/null @@ -1,84 +0,0 @@ -addBoardMember() { - CHECK_VARIABLES MULTISIG - - read -p "Relayer address: " RELAYER_ADDR - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=35000000 --function="addBoardMember" --arguments ${RELAYER_ADDR} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -removeBoardMember() { - CHECK_VARIABLES MULTISIG - - read -p "Relayer address: " RELAYER_ADDR - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ - --gas-limit=35000000 --function="removeUser" --arguments ${RELAYER_ADDR} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -unstake() { - CHECK_VARIABLES MULTISIG RELAYER_REQUIRED_STAKE - - read -p "Relayer address: " RELAYER_ADDR - MIN_STAKE=$(echo "$RELAYER_REQUIRED_STAKE*10^18" | bc) - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem="./walletsRelay/${RELAYER_ADDR}.pem" \ - --gas-limit=35000000 --function="unstake" \ - --arguments ${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -stake() { - CHECK_VARIABLES MULTISIG RELAYER_REQUIRED_STAKE \ - RELAYER_WALLET0 RELAYER_WALLET1 RELAYER_WALLET2 RELAYER_WALLET3 RELAYER_WALLET4 \ - RELAYER_WALLET5 RELAYER_WALLET6 RELAYER_WALLET7 RELAYER_WALLET8 RELAYER_WALLET9 - - MIN_STAKE=$(echo "$RELAYER_REQUIRED_STAKE*10^18" | bc) - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET0} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET1} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET2} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET3} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET4} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET5} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET6} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET7} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET8} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} - echo "---------------------------------------------------------" - echo "---------------------------------------------------------" - mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${RELAYER_WALLET9} \ - --gas-limit=35000000 --function="stake" --value=${MIN_STAKE} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} \ No newline at end of file diff --git a/multisig/interaction/config/safe-snippets.sh b/multisig/interaction/config/safe-snippets.sh deleted file mode 100644 index 636c5cbc..00000000 --- a/multisig/interaction/config/safe-snippets.sh +++ /dev/null @@ -1,35 +0,0 @@ -deploySafe() { - CHECK_VARIABLES SAFE_WASM AGGREGATOR - - mxpy --verbose contract deploy --bytecode=${SAFE_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=150000000 \ - --arguments ${AGGREGATOR} 1 \ - --send --outfile="deploy-safe-testnet.interaction.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return - - TRANSACTION=$(mxpy data parse --file="./deploy-safe-testnet.interaction.json" --expression="data['emittedTransactionHash']") - ADDRESS=$(mxpy data parse --file="./deploy-safe-testnet.interaction.json" --expression="data['contractAddress']") - - mxpy data store --key=address-testnet-safe --value=${ADDRESS} - mxpy data store --key=deployTransaction-testnet --value=${TRANSACTION} - - echo "" - echo "Safe contract address: ${ADDRESS}" -} - -setLocalRolesEsdtSafe() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS CHAIN_SPECIFIC_TOKEN SAFE - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="setSpecialRole" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${SAFE} str:ESDTRoleLocalBurn \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -unsetLocalRolesEsdtSafe() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS CHAIN_SPECIFIC_TOKEN SAFE - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="unSetSpecialRole" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${SAFE} str:ESDTRoleLocalBurn \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} \ No newline at end of file diff --git a/multisig/interaction/config/upgrade-snippets.sh b/multisig/interaction/config/upgrade-snippets.sh deleted file mode 100644 index 5eeb077f..00000000 --- a/multisig/interaction/config/upgrade-snippets.sh +++ /dev/null @@ -1,53 +0,0 @@ -#TODO: check & updates upgrade snippets -deploySafeForUpgrade() { - getAggregatorAddressHex - - local ESDT_SAFE_ETH_TX_GAS_LIMIT=20000 # gives us 200$ for elrond->eth - - mxpy --verbose contract deploy --project=${PROJECT_SAFE} --recall-nonce --pem=${ALICE} \ - --gas-limit=150000000 \ - --arguments 0x${AGGREGATOR_ADDRESS_HEX} ${ESDT_SAFE_ETH_TX_GAS_LIMIT} \ - --send --outfile="deploy-safe-upgrade.interaction.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return - - ADDRESS=$(mxpy data parse --file="./deploy-safe-upgrade.interaction.json" --expression="data['contractAddress']") - - echo "" - echo "Safe contract address: ${ADDRESS}" -} - - -upgradeSafeContract() { - getEsdtSafeAddressHex - getAggregatorAddressHex - local ESDT_SAFE_ETH_TX_GAS_LIMIT=20000 - - local NEW_SAFE_BECH=$(mxpy data parse --file="./deploy-safe-upgrade.interaction.json" --expression="data['contractAddress']") - local NEW_SAFE_ADDR=$(mxpy wallet bech32 --decode $NEW_SAFE_BECH) - - - - mxpy --verbose contract call ${ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=400000000 --function="upgradeChildContractFromSource" \ - --arguments 0x${ESDT_SAFE_ADDRESS_HEX} 0x${NEW_SAFE_ADDR} 0x00 \ - 0x${AGGREGATOR_ADDRESS_HEX} ${ESDT_SAFE_ETH_TX_GAS_LIMIT} \ - --send --outfile="upgradesafe-child-sc-spam.json" --proxy=${PROXY} --chain=${CHAIN_ID} -} - -upgrade() { - mxpy --verbose contract upgrade ${ADDRESS} --project=${PROJECT} --recall-nonce --pem=${ALICE} \ - --gas-limit=100000000 --send --outfile="upgrade.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return -} - -upgradeMultisig() { - getMultiTransferEsdtAddressHex - getEsdtSafeAddressHex - getMultiTransferEsdtAddressHex - - local SLASH_AMOUNT=0x00 # 0 - MIN_STAKE=$(echo "$RELAYER_REQUIRED_STAKE*10^18" | bc) - mxpy --verbose contract upgrade ${ADDRESS} --bytecode=../output/multisig.wasm --recall-nonce --pem=${ALICE} \ - --arguments 0x${ESDT_SAFE_ADDRESS_HEX} 0x${MULTI_TRANSFER_ESDT_ADDRESS_HEX} \ - ${local} ${SLASH_AMOUNT} 0x07 \ - --gas-limit=200000000 --send --outfile="upgrade-multisig.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return - -} \ No newline at end of file diff --git a/multisig/interaction/config/wrapped-snippets.sh b/multisig/interaction/config/wrapped-snippets.sh deleted file mode 100644 index 4985d888..00000000 --- a/multisig/interaction/config/wrapped-snippets.sh +++ /dev/null @@ -1,129 +0,0 @@ -# 1. deployBridgedTokensWrapper -# 3. setLocalRolesBridgedTokensWrapper # - keep in mind we need to do this with the token owner -# 4. addWrappedToken -# 5. whitelistToken -# If the SC already exists, skip the first step -# If we want to add another chain, do only the last step - -deployBridgedTokensWrapper() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER_WASM - - mxpy --verbose contract deploy --bytecode=${BRIDGED_TOKENS_WRAPPER_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=30000000 \ - --send --outfile="deploy-bridged-tokens-wrapper-testnet.interaction.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return - - TRANSACTION=$(mxpy data parse --file="./deploy-bridged-tokens-wrapper-testnet.interaction.json" --expression="data['emittedTransactionHash']") - ADDRESS=$(mxpy data parse --file="./deploy-bridged-tokens-wrapper-testnet.interaction.json" --expression="data['contractAddress']") - - mxpy data store --key=address-testnet-bridged-tokens-wrapper --value=${ADDRESS} - mxpy data store --key=deployTransaction-testnet --value=${TRANSACTION} - - echo "" - echo "Bridged tokens wrapper SC: ${ADDRESS}" -} - -setLocalRolesBridgedTokensWrapper() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS UNIVERSAL_TOKEN BRIDGED_TOKENS_WRAPPER - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="setSpecialRole" \ - --arguments str:${UNIVERSAL_TOKEN} ${BRIDGED_TOKENS_WRAPPER} str:ESDTRoleLocalMint str:ESDTRoleLocalBurn\ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -unsetLocalRolesBridgedTokensWrapper() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS UNIVERSAL_TOKEN BRIDGED_TOKENS_WRAPPER - - mxpy --verbose contract call ${ESDT_SYSTEM_SC_ADDRESS} --recall-nonce --pem=${ALICE} \ - --gas-limit=60000000 --function="unSetSpecialRole" \ - --arguments str:${UNIVERSAL_TOKEN} ${BRIDGED_TOKENS_WRAPPER} str:ESDTRoleLocalMint str:ESDTRoleLocalBurn\ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -addWrappedToken() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER UNIVERSAL_TOKEN NR_DECIMALS_UNIVERSAL - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=6000000 --function="addWrappedToken" \ - --arguments str:${UNIVERSAL_TOKEN} ${NR_DECIMALS_UNIVERSAL} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -removeWrappedToken() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER UNIVERSAL_TOKEN - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=6000000 --function="removeWrappedToken" \ - --arguments str:${UNIVERSAL_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -removeWrappedToken() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER UNIVERSAL_TOKEN - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=6000000 --function="removeWrappedToken" \ - --arguments str:${UNIVERSAL_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -wrapper-whitelistToken() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER CHAIN_SPECIFIC_TOKEN NR_DECIMALS_CHAIN_SPECIFIC UNIVERSAL_TOKEN - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=6000000 --function="whitelistToken" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${NR_DECIMALS_CHAIN_SPECIFIC} str:${UNIVERSAL_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -wrapper-blacklistToken() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER CHAIN_SPECIFIC_TOKEN UNIVERSAL_TOKEN - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=6000000 --function="blacklistToken" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -wrapper-updateWrappedToken() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER UNIVERSAL_TOKEN NR_DECIMALS_UNIVERSAL - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=6000000 --function="updateWrappedToken" \ - --arguments str:${UNIVERSAL_TOKEN} ${NR_DECIMALS_UNIVERSAL} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - -wrapper-updateWhitelistedToken() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER CHAIN_SPECIFIC_TOKEN NR_DECIMALS_CHAIN_SPECIFIC - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=6000000 --function="updateWhitelistedToken" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} ${NR_DECIMALS_CHAIN_SPECIFIC} \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} -} - - -wrapper-unpause() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=5000000 --function="unpause" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} || return -} - -wrapper-pause() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER - - mxpy --verbose contract call ${BRIDGED_TOKENS_WRAPPER} --recall-nonce --pem=${ALICE} \ - --gas-limit=5000000 --function="pause" \ - --send --proxy=${PROXY} --chain=${CHAIN_ID} || return -} - -wrapper-upgrade() { - CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER BRIDGED_TOKENS_WRAPPER_WASM - - mxpy --verbose contract upgrade ${BRIDGED_TOKENS_WRAPPER} --bytecode=${BRIDGED_TOKENS_WRAPPER_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=50000000 --send \ - --outfile="upgrade-bridged-tokens-wrapper.json" --proxy=${PROXY} --chain=${CHAIN_ID} || return -} \ No newline at end of file diff --git a/multisig/interaction/script.sh b/multisig/interaction/script.sh deleted file mode 100755 index ed684a2a..00000000 --- a/multisig/interaction/script.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/bash -set -e - -#Make script aware of its location -SCRIPTPATH="$( cd "$(dirname -- "$0")" ; pwd -P )" - -source $SCRIPTPATH/config/configs.cfg -source $SCRIPTPATH/config/helper.cfg -source $SCRIPTPATH/config/menu_functions.cfg - -case "$1" in -'deploy-aggregator') - confirmation deploy-aggregator - ;; - -'deploy-wrapper') - confirmation deploy-wrapper - ;; - -'upgrade-wrapper') - confirmation upgrade-wrapper - ;; - -'deploy-bridge-contracts') - echo -e - echo "PREREQUIREMENTS: AGGREGATOR & BRIDGED_TOKENS_WRAPPER deployed" - echo -e - confirmation deploy-bridge-contracts - ;; - -'add-relayer') - confirmation addBoardMember - ;; - -'remove-relayer') - confirmation removeBoardMember - ;; - -'whitelist-token') - echo -e - echo "PREREQUIREMENTS: BRIDGED_TOKENS_WRAPPER needs to have MINT+BURN role for the UNIVERSAL TOKEN" - echo "Check and update TOKENS SETTINGS section in configs.cfg" - source $SCRIPTPATH/config/configs.cfg - echo -e - confirmation whitelist-token - ;; - -'remove-whitelist-token') - echo -e - echo "PREREQUIREMENTS: BRIDGED_TOKENS_WRAPPER needs to have MINT+BURN role for the UNIVERSAL TOKEN" - echo "Check and update TOKENS SETTINGS section in configs.cfg" - source $SCRIPTPATH/config/configs.cfg - echo -e - confirmation remove-whitelist-token - ;; - -'set-safe-max-tx') - confirmation set-safe-max-tx - ;; - -'set-safe-batch-block-duration') - confirmation set-safe-batch-block-duration - ;; - -'change-quorum') - confirmation change-quorum - ;; - -'pause-contracts') - confirmation pause-contracts - ;; - -'unpause-contracts') - confirmation unpause-contracts - ;; - -'set-swap-fee') - confirmation set-fee - ;; - -'mint-chain-specific') - confirmation mint-chain-specific - ;; - -'upgrade-wrapper-universal-token') - confirmation upgrade-wrapper-universal-token - ;; - -'upgrade-wrapper-chain-specific-token') - confirmation upgrade-wrapper-chain-specific-token - ;; - -*) - echo "Usage: Invalid choice: '"$1"'" - echo -e - echo "Choose from:" - echo " { \"deploy-aggregator\", \"deploy-wrapper\", \"upgrade-wrapper\", \"deploy-bridge-contracts\", \"add-relayer\", \"remove-relayer\", \"whitelist-token\", " - echo " \"remove-whitelist-token\", \"set-safe-max-tx\", \"set-safe-batch-block-duration\", \"change-quorum\", \"pause-contracts\", \"unpause-contracts\", " - echo " \"set-swap-fee\", \"mint-chain-specific\", \"upgrade-wrapper-universal-token\", \"upgrade-wrapper-chain-specific-token\" }" - ;; - -esac \ No newline at end of file diff --git a/multisig/meta/Cargo.toml b/multisig/meta/Cargo.toml deleted file mode 100644 index b5d97d75..00000000 --- a/multisig/meta/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "multisig-meta" -version = "0.0.0" -authors = ["Andrei Marinica , Dorin Iancu "] -edition = "2018" -publish = false -[dependencies.multisig] -path = ".." - -[dependencies.multiversx-sc-meta] -version = "0.43.4" diff --git a/multisig/meta/src/main.rs b/multisig/meta/src/main.rs deleted file mode 100644 index 69a0a648..00000000 --- a/multisig/meta/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - multiversx_sc_meta::cli_main::(); -} diff --git a/multisig/multiversx.json b/multisig/multiversx.json deleted file mode 100644 index 8d77ca31..00000000 --- a/multisig/multiversx.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "language": "rust" -} diff --git a/multisig/src/action.rs b/multisig/src/action.rs deleted file mode 100644 index 40dcce57..00000000 --- a/multisig/src/action.rs +++ /dev/null @@ -1,28 +0,0 @@ -use multiversx_sc::api::ManagedTypeApi; -use multiversx_sc::types::ManagedVec; -use transaction::transaction_status::TransactionStatus; -use transaction::Transaction; - -multiversx_sc::derive_imports!(); - -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] -pub enum Action { - Nothing, - SetCurrentTransactionBatchStatus { - esdt_safe_batch_id: u64, - tx_batch_status: ManagedVec, - }, - BatchTransferEsdtToken { - sov_batch_id: u64, - transfers: ManagedVec>, - }, -} - -impl Action { - /// Only pending actions are kept in storage, - /// both executed and discarded actions are removed (converted to `Nothing`). - /// So this is equivalent to `action != Action::Nothing`. - pub fn is_pending(&self) -> bool { - !matches!(*self, Action::Nothing) - } -} diff --git a/multisig/src/lib.rs b/multisig/src/lib.rs deleted file mode 100644 index 3f14f488..00000000 --- a/multisig/src/lib.rs +++ /dev/null @@ -1,334 +0,0 @@ -#![no_std] -#![allow(clippy::too_many_arguments)] - -mod action; -mod multisig_general; -mod queries; -mod setup; -mod storage; -mod user_role; -mod util; - -use action::Action; -use transaction::transaction_status::TransactionStatus; -use transaction::TxBatchSplitInFields; -use transaction::*; -use user_role::UserRole; - -use esdt_safe::ProxyTrait as _; -use multi_transfer_esdt::ProxyTrait as _; -use tx_batch_module::ProxyTrait as _; - -multiversx_sc::imports!(); - -/// Multi-signature smart contract implementation. -/// Acts like a wallet that needs multiple signers for any action performed. -#[multiversx_sc::contract] -pub trait Multisig: - multisig_general::MultisigGeneralModule - + setup::SetupModule - + storage::StorageModule - + util::UtilModule - + queries::QueriesModule - + multiversx_sc_modules::pause::PauseModule -{ - /// EsdtSafe and MultiTransferEsdt are expected to be deployed and configured separately, - /// and then having their ownership changed to this Multisig SC. - #[init] - fn init( - &self, - esdt_safe_sc_address: ManagedAddress, - multi_transfer_sc_address: ManagedAddress, - required_stake: BigUint, - slash_amount: BigUint, - quorum: usize, - board: MultiValueEncoded, - ) { - let mut duplicates = false; - let board_len = board.len(); - self.user_mapper() - .get_or_create_users(board.into_iter(), |user_id, new_user| { - if !new_user { - duplicates = true; - } - self.user_id_to_role(user_id).set(UserRole::BoardMember); - }); - require!(!duplicates, "duplicate board member"); - - self.num_board_members() - .update(|nr_board_members| *nr_board_members += board_len); - self.change_quorum(quorum); - - require!( - slash_amount <= required_stake, - "slash amount must be less than or equal to required stake" - ); - self.required_stake_amount().set(&required_stake); - self.slash_amount().set(&slash_amount); - - require!( - self.blockchain().is_smart_contract(&esdt_safe_sc_address), - "Esdt Safe address is not a Smart Contract address" - ); - self.esdt_safe_address().set(&esdt_safe_sc_address); - - require!( - self.blockchain() - .is_smart_contract(&multi_transfer_sc_address), - "Multi Transfer address is not a Smart Contract address" - ); - self.multi_transfer_esdt_address() - .set(&multi_transfer_sc_address); - - self.set_paused(true); - } - - #[endpoint] - fn upgrade(&self) {} - - /// Board members have to stake a certain amount of EGLD - /// before being allowed to sign actions - #[payable("EGLD")] - #[endpoint] - fn stake(&self) { - let egld_payment = self.call_value().egld_value().clone_value(); - let caller = self.blockchain().get_caller(); - let caller_role = self.user_role(&caller); - require!( - caller_role == UserRole::BoardMember, - "Only board members can stake" - ); - - self.amount_staked(&caller) - .update(|amount_staked| *amount_staked += egld_payment); - } - - #[endpoint] - fn unstake(&self, amount: BigUint) { - let caller = self.blockchain().get_caller(); - let amount_staked = self.amount_staked(&caller).get(); - require!( - amount <= amount_staked, - "can't unstake more than amount staked" - ); - - let remaining_stake = &amount_staked - &amount; - if self.user_role(&caller) == UserRole::BoardMember { - let required_stake_amount = self.required_stake_amount().get(); - require!( - remaining_stake >= required_stake_amount, - "can't unstake, must keep minimum amount as insurance" - ); - } - - self.amount_staked(&caller).set(&remaining_stake); - self.send().direct_egld(&caller, &amount); - } - - // ESDT Safe SC calls - - /// After a batch is processed on the Sovereign side, - /// the EsdtSafe expects a list of statuses of said transactions (success or failure). - /// - /// This endpoint proposes an action to set the statuses to a certain list of values. - /// Nothing is changed in the EsdtSafe contract until the action is signed and executed. - #[endpoint(proposeEsdtSafeSetCurrentTransactionBatchStatus)] - fn propose_esdt_safe_set_current_transaction_batch_status( - &self, - esdt_safe_batch_id: u64, - tx_batch_status: MultiValueEncoded, - ) -> usize { - let call_result: OptionalValue> = self - .get_esdt_safe_proxy_instance() - .get_current_tx_batch() - .execute_on_dest_context(); - let (current_batch_id, current_batch_transactions) = match call_result { - OptionalValue::Some(batch) => batch.into_tuple(), - OptionalValue::None => sc_panic!("Current batch is empty"), - }; - let statuses_vec = tx_batch_status.to_vec(); - - require!( - self.action_id_for_set_current_transaction_batch_status(esdt_safe_batch_id) - .get(&statuses_vec) - .is_none(), - "Action already proposed" - ); - - let current_batch_len = current_batch_transactions.raw_len() / TX_MULTIRESULT_NR_FIELDS; - let status_batch_len = statuses_vec.len(); - require!( - current_batch_len == status_batch_len, - "Number of statuses provided must be equal to number of transactions in current batch" - ); - require!( - esdt_safe_batch_id == current_batch_id, - "Current EsdtSafe tx batch does not have the provided ID" - ); - - let action_id = self.propose_action(Action::SetCurrentTransactionBatchStatus { - esdt_safe_batch_id, - tx_batch_status: statuses_vec.clone(), - }); - - self.action_id_for_set_current_transaction_batch_status(esdt_safe_batch_id) - .insert(statuses_vec, action_id); - - action_id - } - - // Multi-transfer ESDT SC calls - - /// Proposes a batch of Sovereign -> Elrond transfers. - /// Transactions have to be separated by fields, in the following order: - /// Sender Address, Destination Address, Token ID, Amount, Tx Nonce - #[endpoint(proposeMultiTransferEsdtBatch)] - fn propose_multi_transfer_esdt_batch( - &self, - sov_batch_id: u64, - transfers: MultiValueEncoded>, - ) -> usize { - let next_sov_batch_id = self.last_executed_sov_batch_id().get() + 1; - require!( - sov_batch_id == next_sov_batch_id, - "Can only propose for next batch ID" - ); - - let transfers_as_sov_tx = self.transfers_multi_value_to_sov_tx_vec(transfers); - self.require_valid_sov_tx_ids(&transfers_as_sov_tx); - - let batch_hash = self.hash_sov_tx_batch(&transfers_as_sov_tx); - require!( - self.batch_id_to_action_id_mapping(sov_batch_id) - .get(&batch_hash) - .is_none(), - "This batch was already proposed" - ); - - let action_id = self.propose_action(Action::BatchTransferEsdtToken { - sov_batch_id, - transfers: transfers_as_sov_tx, - }); - - self.batch_id_to_action_id_mapping(sov_batch_id) - .insert(batch_hash, action_id); - - action_id - } - - /// Failed Sovereign -> Elrond transactions are saved in the MultiTransfer SC - /// as "refund transactions", and stored in batches, using the same mechanism as EsdtSafe. - /// - /// This function moves the first refund batch into the EsdtSafe SC, - /// converting the transactions into Elrond -> Sovereign transactions - /// and adding them into EsdtSafe batches - #[only_owner] - #[endpoint(moveRefundBatchToSafe)] - fn move_refund_batch_to_safe(&self) { - let opt_refund_batch_fields: OptionalValue> = self - .get_multi_transfer_esdt_proxy_instance() - .get_and_clear_first_refund_batch() - .execute_on_dest_context(); - - if let OptionalValue::Some(refund_batch_fields) = opt_refund_batch_fields { - let (_batch_id, all_tx_fields) = refund_batch_fields.into_tuple(); - let mut refund_batch = ManagedVec::new(); - - for tx_fields in all_tx_fields { - refund_batch.push(Transaction::from(tx_fields)); - } - - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .add_refund_batch(refund_batch) - .execute_on_dest_context(); - } - } - - /// Proposers and board members use this to launch signed actions. - #[endpoint(performAction)] - fn perform_action_endpoint(&self, action_id: usize) { - require!( - !self.action_mapper().item_is_empty(action_id), - "Action was already executed" - ); - - let caller_address = self.blockchain().get_caller(); - let caller_role = self.get_user_role(&caller_address); - require!( - caller_role.is_board_member(), - "only board members can perform actions" - ); - require!( - self.quorum_reached(action_id), - "quorum has not been reached" - ); - require!(self.not_paused(), "No actions may be executed while paused"); - - self.perform_action(action_id); - } - - // private - - fn perform_action(&self, action_id: usize) { - let action = self.action_mapper().get(action_id); - self.clear_action(action_id); - - match action { - Action::Nothing => {} - Action::SetCurrentTransactionBatchStatus { - esdt_safe_batch_id, - tx_batch_status, - } => { - let mut action_ids_mapper = - self.action_id_for_set_current_transaction_batch_status(esdt_safe_batch_id); - - // if there's only one proposed action, - // the action was already cleared at the beginning of this function - if action_ids_mapper.len() > 1 { - for act_id in action_ids_mapper.values() { - self.clear_action(act_id); - } - } - - action_ids_mapper.clear(); - - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .set_transaction_batch_status( - esdt_safe_batch_id, - MultiValueEncoded::from(tx_batch_status), - ) - .execute_on_dest_context(); - } - Action::BatchTransferEsdtToken { - sov_batch_id, - transfers, - } => { - let mut action_ids_mapper = self.batch_id_to_action_id_mapping(sov_batch_id); - - // if there's only one proposed action, - // the action was already cleared at the beginning of this function - if action_ids_mapper.len() > 1 { - for act_id in action_ids_mapper.values() { - self.clear_action(act_id); - } - } - - action_ids_mapper.clear(); - self.last_executed_sov_batch_id().update(|id| *id += 1); - - let last_tx_index = transfers.len() - 1; - let last_tx = transfers.get(last_tx_index); - self.last_executed_sov_tx_id().set(last_tx.nonce); - - let transfers_multi: MultiValueEncoded> = - transfers.into(); - let _: IgnoreValue = self - .get_multi_transfer_esdt_proxy_instance() - .batch_transfer_esdt_token(sov_batch_id, transfers_multi) - .execute_on_dest_context(); - } - } - } -} diff --git a/multisig/src/multisig_general.rs b/multisig/src/multisig_general.rs deleted file mode 100644 index c044e663..00000000 --- a/multisig/src/multisig_general.rs +++ /dev/null @@ -1,73 +0,0 @@ -multiversx_sc::imports!(); - -use crate::action::Action; -use crate::user_role::UserRole; - -#[multiversx_sc::module] -pub trait MultisigGeneralModule: - crate::util::UtilModule + crate::storage::StorageModule + multiversx_sc_modules::pause::PauseModule -{ - /// Used by board members to sign actions. - #[endpoint] - fn sign(&self, action_id: usize) { - require!( - !self.action_mapper().item_is_empty_unchecked(action_id), - "action does not exist" - ); - - let caller_address = self.blockchain().get_caller(); - let caller_id = self.user_mapper().get_user_id(&caller_address); - let caller_role = self.user_id_to_role(caller_id).get(); - require!(caller_role.is_board_member(), "only board members can sign"); - require!(self.has_enough_stake(&caller_address), "not enough stake"); - - let _ = self.action_signer_ids(action_id).insert(caller_id); - } - - fn propose_action(&self, action: Action) -> usize { - let caller_address = self.blockchain().get_caller(); - let caller_id = self.user_mapper().get_user_id(&caller_address); - let caller_role = self.user_id_to_role(caller_id).get(); - require!( - caller_role.is_board_member(), - "only board members can propose" - ); - - require!(self.not_paused(), "No actions may be proposed while paused"); - - let action_id = self.action_mapper().push(&action); - if self.has_enough_stake(&caller_address) { - let _ = self.action_signer_ids(action_id).insert(caller_id); - } - - action_id - } - - fn clear_action(&self, action_id: usize) { - self.action_mapper().clear_entry_unchecked(action_id); - self.action_signer_ids(action_id).clear(); - } - - fn add_board_member(&self, user_address: &ManagedAddress) { - let user_id = self.user_mapper().get_or_create_user(user_address); - let old_role = self.user_id_to_role(user_id).get(); - - if !old_role.is_board_member() { - self.num_board_members().update(|value| *value += 1); - self.user_id_to_role(user_id).set(UserRole::BoardMember); - } - } - - fn remove_board_member(&self, user_address: &ManagedAddress) { - let user_id = self.user_mapper().get_user_id(user_address); - if user_id == 0 { - return; - } - - let old_role = self.user_id_to_role(user_id).get(); - if old_role.is_board_member() { - self.num_board_members().update(|value| *value -= 1); - self.user_id_to_role(user_id).set(UserRole::None); - } - } -} diff --git a/multisig/src/queries.rs b/multisig/src/queries.rs deleted file mode 100644 index 3b3fbd52..00000000 --- a/multisig/src/queries.rs +++ /dev/null @@ -1,193 +0,0 @@ -multiversx_sc::imports!(); - -use crate::{action::Action, user_role::UserRole}; -use transaction::{transaction_status::TransactionStatus, TxBatchSplitInFields, TxAsMultiValue}; - -use tx_batch_module::ProxyTrait as _; - -/// Note: Additional queries can be found in the Storage module -#[multiversx_sc::module] -pub trait QueriesModule: crate::storage::StorageModule + crate::util::UtilModule { - /// Returns the current EsdtSafe batch. - /// - /// First result is the batch ID, then pairs of 7 results, representing transactions - /// split by fields: - /// - /// Block Nonce, Tx Nonce, Sender Address, Receiver Address, Token IDs, Token data, Opt transfer data - #[view(getCurrentTxBatch)] - fn get_current_tx_batch(&self) -> OptionalValue> { - self.get_esdt_safe_proxy_instance() - .get_current_tx_batch() - .execute_on_dest_context() - } - - /// Returns a batch of failed Sovereign -> Elrond transactions. - /// The result format is the same as getCurrentTxBatch - #[view(getCurrentRefundBatch)] - fn get_current_refund_batch(&self) -> OptionalValue> { - self.get_multi_transfer_esdt_proxy_instance() - .get_first_batch_any_status() - .execute_on_dest_context() - } - - /// Actions are cleared after execution, so an empty entry means the action was executed already - /// Returns "false" if the action ID is invalid - #[view(wasActionExecuted)] - fn was_action_executed(&self, action_id: usize) -> bool { - if self.is_valid_action_id(action_id) { - self.action_mapper().item_is_empty(action_id) - } else { - false - } - } - - /// Used for Sovereign -> Elrond batches. - /// If the mapping was made, it means that the transfer action was proposed in the past. - /// To check if it was executed as well, use the wasActionExecuted view - #[view(wasTransferActionProposed)] - fn was_transfer_action_proposed( - &self, - sov_batch_id: u64, - transfers: MultiValueEncoded>, - ) -> bool { - let action_id = self.get_action_id_for_transfer_batch(sov_batch_id, transfers); - - self.is_valid_action_id(action_id) - } - - /// Used for TxBatchSplitInFields -> Elrond batches. - /// If `wasActionExecuted` returns true, then this can be used to get the action ID. - /// Will return 0 if the transfers were not proposed - #[view(getActionIdForTransferBatch)] - fn get_action_id_for_transfer_batch( - &self, - sov_batch_id: u64, - transfers: MultiValueEncoded>, - ) -> usize { - let transfers_as_struct = self.transfers_multi_value_to_sov_tx_vec(transfers); - let batch_hash = self.hash_sov_tx_batch(&transfers_as_struct); - - self.batch_id_to_action_id_mapping(sov_batch_id) - .get(&batch_hash) - .unwrap_or(0) - } - - /// Used for Elrond -> Sovereign batches. - /// Returns "true" if an action was already proposed for the given batch, - /// with these exact transaction statuses, in this exact order - #[view(wasSetCurrentTransactionBatchStatusActionProposed)] - fn was_set_current_transaction_batch_status_action_proposed( - &self, - esdt_safe_batch_id: u64, - expected_tx_batch_status: MultiValueEncoded, - ) -> bool { - self.is_valid_action_id(self.get_action_id_for_set_current_transaction_batch_status( - esdt_safe_batch_id, - expected_tx_batch_status, - )) - } - - /// If `wasSetCurrentTransactionBatchStatusActionProposed` return true, - /// this can be used to get the action ID. - /// Will return 0 if the set status action was not proposed - #[view(getActionIdForSetCurrentTransactionBatchStatus)] - fn get_action_id_for_set_current_transaction_batch_status( - &self, - esdt_safe_batch_id: u64, - expected_tx_batch_status: MultiValueEncoded, - ) -> usize { - self.action_id_for_set_current_transaction_batch_status(esdt_safe_batch_id) - .get(&expected_tx_batch_status.to_vec()) - .unwrap_or(0) - } - - /// Returns `true` (`1`) if the user has signed the action. - /// Does not check whether or not the user is still a board member and the signature valid. - #[view] - fn signed(&self, user: ManagedAddress, action_id: usize) -> bool { - let user_id = self.user_mapper().get_user_id(&user); - if user_id == 0 { - false - } else { - self.action_signer_ids(action_id).contains(&user_id) - } - } - - /// Indicates user rights. - /// `0` = no rights, - /// `1` = can propose. Can also sign if they have enough stake. - #[view(userRole)] - fn user_role(&self, user: &ManagedAddress) -> UserRole { - self.get_user_role(user) - } - - /// Lists all board members - #[view(getAllBoardMembers)] - fn get_all_board_members(&self) -> MultiValueEncoded { - self.get_all_users_with_role(UserRole::BoardMember) - } - - /// Lists all board members that staked the correct amount. - /// A board member with not enough stake can propose, but cannot sign. - #[view(getAllStakedRelayers)] - fn get_all_staked_relayers(&self) -> MultiValueEncoded { - let relayers = self.get_all_board_members().to_vec(); - let mut staked_relayers = ManagedVec::new(); - - for relayer in &relayers { - if self.has_enough_stake(&relayer) { - staked_relayers.push(relayer); - } - } - - staked_relayers.into() - } - - /// Gets the number of signatures for the action with the given ID - #[view(getActionSignerCount)] - fn get_action_signer_count(&self, action_id: usize) -> usize { - self.action_signer_ids(action_id).len() - } - - /// It is possible for board members to lose their role. - /// They are not automatically removed from all actions when doing so, - /// therefore the contract needs to re-check every time when actions are performed. - /// This function is used to validate the signers before performing an action. - /// It also makes it easy to check before performing an action. - #[view(getActionValidSignerCount)] - fn get_action_valid_signer_count(&self, action_id: usize) -> usize { - self.action_signer_ids(action_id) - .iter() - .filter(|signer_id| { - let signer_role = self.user_id_to_role(*signer_id).get(); - let signer_address = self - .user_mapper() - .get_user_address(*signer_id) - .unwrap_or_default(); - - signer_role.is_board_member() && self.has_enough_stake(&signer_address) - }) - .count() - } - - /// Returns `true` (`1`) if `getActionValidSignerCount >= getQuorum`. - #[view(quorumReached)] - fn quorum_reached(&self, action_id: usize) -> bool { - let quorum = self.quorum().get(); - let valid_signers_count = self.get_action_valid_signer_count(action_id); - valid_signers_count >= quorum - } - - /// The index of the last proposed action. - /// 0 means that no action was ever proposed yet. - #[view(getActionLastIndex)] - fn get_action_last_index(&self) -> usize { - self.action_mapper().len() - } - - /// Serialized action data of an action with index. - #[view(getActionData)] - fn get_action_data(&self, action_id: usize) -> Action { - self.action_mapper().get(action_id) - } -} diff --git a/multisig/src/setup.rs b/multisig/src/setup.rs deleted file mode 100644 index a22931dd..00000000 --- a/multisig/src/setup.rs +++ /dev/null @@ -1,276 +0,0 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); - -use max_bridged_amount_module::ProxyTrait as _; -use multi_transfer_esdt::ProxyTrait as _; -use multiversx_sc_modules::pause::ProxyTrait as _; -use token_module::ProxyTrait as _; -use tx_batch_module::ProxyTrait as _; - -#[multiversx_sc::module] -pub trait SetupModule: - crate::multisig_general::MultisigGeneralModule - + crate::storage::StorageModule - + crate::util::UtilModule - + multiversx_sc_modules::pause::PauseModule -{ - #[only_owner] - #[endpoint(upgradeChildContractFromSource)] - fn upgrade_child_contract_from_source( - &self, - child_sc_address: ManagedAddress, - source_address: ManagedAddress, - is_payable: bool, - init_args: MultiValueEncoded, - ) { - let mut metadata = CodeMetadata::UPGRADEABLE; - if is_payable { - metadata |= CodeMetadata::PAYABLE_BY_SC; - } - - let gas = self.blockchain().get_gas_left(); - self.send_raw().upgrade_from_source_contract( - &child_sc_address, - gas, - &BigUint::zero(), - &source_address, - metadata, - &init_args.to_arg_buffer(), - ); - } - - #[only_owner] - #[endpoint(addBoardMember)] - fn add_board_member_endpoint(&self, board_member: ManagedAddress) { - self.add_board_member(&board_member); - } - - #[only_owner] - #[endpoint(removeUser)] - fn remove_user(&self, board_member: ManagedAddress) { - self.remove_board_member(&board_member); - let num_board_members = self.num_board_members().get(); - require!(num_board_members > 0, "cannot remove all board members"); - require!( - self.quorum().get() <= num_board_members, - "quorum cannot exceed board size" - ); - } - - /// Cuts a fixed amount from a board member's stake. - /// This should be used only in cases where the board member - /// is being actively malicious. - /// - /// After stake is cut, the board member would have to stake again - /// to be able to sign actions. - #[only_owner] - #[endpoint(slashBoardMember)] - fn slash_board_member(&self, board_member: ManagedAddress) { - self.remove_user(board_member.clone()); - - let slash_amount = self.slash_amount().get(); - - // remove slashed amount from user stake amountself - self.amount_staked(&board_member) - .update(|stake| *stake -= &slash_amount); - - // add it to total slashed amount pool - self.slashed_tokens_amount() - .update(|slashed_amt| *slashed_amt += slash_amount); - } - - #[only_owner] - #[endpoint(changeQuorum)] - fn change_quorum(&self, new_quorum: usize) { - require!( - new_quorum <= self.num_board_members().get(), - "quorum cannot exceed board size" - ); - self.quorum().set(new_quorum); - } - - /// Maps an ESDT token to a Sovereign ESDT token. Used by relayers. - #[only_owner] - #[endpoint(addMapping)] - fn add_mapping(&self, sov_token_id: TokenIdentifier, elrond_token_id: TokenIdentifier) { - require!( - self.sov_token_id_for_elrond_token_id(&elrond_token_id) - .is_empty(), - "Mapping already exists for token ID" - ); - require!( - self.elrond_token_id_for_sov_token_id(&sov_token_id) - .is_empty(), - "Mapping already exists for ERC20 token" - ); - - self.sov_token_id_for_elrond_token_id(&elrond_token_id) - .set(&sov_token_id); - self.elrond_token_id_for_sov_token_id(&sov_token_id) - .set(&elrond_token_id); - } - - #[only_owner] - #[endpoint(clearMapping)] - fn clear_mapping(&self, sov_token_id: TokenIdentifier, elrond_token_id: TokenIdentifier) { - require!( - !self - .sov_token_id_for_elrond_token_id(&elrond_token_id) - .is_empty(), - "Mapping does not exist for ERC20 token" - ); - require!( - !self - .elrond_token_id_for_sov_token_id(&sov_token_id) - .is_empty(), - "Mapping does not exist for token id" - ); - - let mapped_sov_token_id = self - .sov_token_id_for_elrond_token_id(&elrond_token_id) - .get(); - let mapped_elrond_token_id = self.elrond_token_id_for_sov_token_id(&sov_token_id).get(); - - require!( - sov_token_id == mapped_sov_token_id && elrond_token_id == mapped_elrond_token_id, - "Invalid mapping" - ); - - self.sov_token_id_for_elrond_token_id(&elrond_token_id) - .clear(); - self.elrond_token_id_for_sov_token_id(&sov_token_id).clear(); - } - - #[only_owner] - #[endpoint(pauseEsdtSafe)] - fn pause_esdt_safe(&self) { - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .pause_endpoint() - .execute_on_dest_context(); - } - - #[only_owner] - #[endpoint(unpauseEsdtSafe)] - fn unpause_esdt_safe(&self) { - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .unpause_endpoint() - .execute_on_dest_context(); - } - - #[only_owner] - #[endpoint(esdtSafeAddTokenToWhitelist)] - fn esdt_safe_add_token_to_whitelist(&self, token_id: TokenIdentifier, ticker: ManagedBuffer) { - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .add_token_to_whitelist(token_id, ticker) - .execute_on_dest_context(); - } - - #[only_owner] - #[endpoint(esdtSafeRemoveTokenFromWhitelist)] - fn esdt_safe_remove_token_from_whitelist(&self, token_id: TokenIdentifier) { - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .remove_token_from_whitelist(token_id) - .execute_on_dest_context(); - } - - /// Sets maximum batch size for the EsdtSafe SC. - /// If a batch reaches this amount of transactions, it is considered full, - /// and a new incoming transaction will be put into a new batch. - #[only_owner] - #[endpoint(esdtSafeSetMaxTxBatchSize)] - fn esdt_safe_set_max_tx_batch_size(&self, new_max_tx_batch_size: usize) { - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .set_max_tx_batch_size(new_max_tx_batch_size) - .execute_on_dest_context(); - } - - /// Sets the maximum block duration in which an EsdtSafe batch accepts transactions - /// For a batch to be considered "full", it has to either reach `maxTxBatchSize` transactions, - /// or have txBatchBlockDuration blocks pass since the first tx was added in the batch - #[only_owner] - #[endpoint(esdtSafeSetMaxTxBatchBlockDuration)] - fn esdt_safe_set_max_tx_batch_block_duration(&self, new_max_tx_batch_block_duration: u64) { - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .set_max_tx_batch_block_duration(new_max_tx_batch_block_duration) - .execute_on_dest_context(); - } - - /// Sets the maximum bridged amount for the token for the Elrond -> Sovereign direction. - /// Any attempt to transfer over this amount will be rejected. - #[only_owner] - #[endpoint(esdtSafeSetMaxBridgedAmountForToken)] - fn esdt_safe_set_max_bridged_amount_for_token( - &self, - token_id: TokenIdentifier, - max_amount: BigUint, - ) { - let _: IgnoreValue = self - .get_esdt_safe_proxy_instance() - .set_max_bridged_amount(token_id, max_amount) - .execute_on_dest_context(); - } - - /// Same as the function above, but for Sovereign -> Elrond transactions. - #[only_owner] - #[endpoint(multiTransferEsdtSetMaxBridgedAmountForToken)] - fn multi_transfer_esdt_set_max_bridged_amount_for_token( - &self, - token_id: TokenIdentifier, - max_amount: BigUint, - ) { - let _: IgnoreValue = self - .get_multi_transfer_esdt_proxy_instance() - .set_max_bridged_amount(token_id, max_amount) - .execute_on_dest_context(); - } - - /// Any failed Sovereign -> Elrond transactions are added into so-called "refund batches" - /// This configures the size of a batch. - #[only_owner] - #[endpoint(multiTransferEsdtSetMaxRefundTxBatchSize)] - fn multi_transfer_esdt_set_max_refund_tx_batch_size(&self, new_max_tx_batch_size: usize) { - let _: IgnoreValue = self - .get_multi_transfer_esdt_proxy_instance() - .set_max_tx_batch_size(new_max_tx_batch_size) - .execute_on_dest_context(); - } - - /// Max block duration for refund batches. Default is "infinite" (u64::MAX) - /// and only max batch size matters - #[only_owner] - #[endpoint(multiTransferEsdtSetMaxRefundTxBatchBlockDuration)] - fn multi_transfer_esdt_set_max_refund_tx_batch_block_duration( - &self, - new_max_tx_batch_block_duration: u64, - ) { - let _: IgnoreValue = self - .get_multi_transfer_esdt_proxy_instance() - .set_max_tx_batch_block_duration(new_max_tx_batch_block_duration) - .execute_on_dest_context(); - } - - /// Sets the wrapping contract address. - /// This contract is used to map multiple tokens to a universal one. - /// Useful in cases where a single token (USDC for example) - /// is being transferred from multiple chains. - /// - /// They will all have different token IDs, but can be swapped 1:1 in the wrapping SC. - /// The wrapping is done automatically, so the user only receives the universal token. - #[only_owner] - #[endpoint(multiTransferEsdtSetWrappingContractAddress)] - fn multi_transfer_esdt_set_wrapping_contract_address( - &self, - opt_wrapping_contract_address: OptionalValue, - ) { - let _: IgnoreValue = self - .get_multi_transfer_esdt_proxy_instance() - .set_wrapping_contract_address(opt_wrapping_contract_address) - .execute_on_dest_context(); - } -} diff --git a/multisig/src/storage.rs b/multisig/src/storage.rs deleted file mode 100644 index fcb87b1a..00000000 --- a/multisig/src/storage.rs +++ /dev/null @@ -1,101 +0,0 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); - -use transaction::transaction_status::TransactionStatus; - -use crate::action::Action; -use crate::user_role::UserRole; - -pub type SovBatchHash = ManagedByteArray; // keccak256(ManagedVec) - -#[multiversx_sc::module] -pub trait StorageModule { - /// Minimum number of signatures needed to perform any action. - #[view(getQuorum)] - #[storage_mapper("quorum")] - fn quorum(&self) -> SingleValueMapper; - - #[storage_mapper("user")] - fn user_mapper(&self) -> UserMapper; - - #[storage_mapper("user_role")] - fn user_id_to_role(&self, user_id: usize) -> SingleValueMapper; - - /// Denormalized board member count. - /// It is kept in sync with the user list by the contract. - #[view(getNumBoardMembers)] - #[storage_mapper("num_board_members")] - fn num_board_members(&self) -> SingleValueMapper; - - #[storage_mapper("action_data")] - fn action_mapper(&self) -> VecMapper>; - - #[storage_mapper("action_signer_ids")] - fn action_signer_ids(&self, action_id: usize) -> UnorderedSetMapper; - - /// The required amount to stake for accepting relayer position - #[view(getRequiredStakeAmount)] - #[storage_mapper("requiredStakeAmount")] - fn required_stake_amount(&self) -> SingleValueMapper; - - /// Staked amount by each board member. - #[view(getAmountStaked)] - #[storage_mapper("amountStaked")] - fn amount_staked(&self, board_member_address: &ManagedAddress) -> SingleValueMapper; - - /// Amount of stake slashed if a relayer is misbehaving - #[view(getSlashAmount)] - #[storage_mapper("slashAmount")] - fn slash_amount(&self) -> SingleValueMapper; - - /// Total slashed tokens accumulated - #[view(getSlashedTokensAmount)] - #[storage_mapper("slashedTokensAmount")] - fn slashed_tokens_amount(&self) -> SingleValueMapper; - - #[view(getLastExecutedSovBatchId)] - #[storage_mapper("lastExecutedSovBatchId")] - fn last_executed_sov_batch_id(&self) -> SingleValueMapper; - - #[view(getLastExecutedSovTxId)] - #[storage_mapper("lastExecutedSovTxId")] - fn last_executed_sov_tx_id(&self) -> SingleValueMapper; - - #[storage_mapper("batchIdToActionIdMapping")] - fn batch_id_to_action_id_mapping( - &self, - batch_id: u64, - ) -> MapMapper, usize>; - - #[storage_mapper("actionIdForSetCurrentTransactionBatchStatus")] - fn action_id_for_set_current_transaction_batch_status( - &self, - esdt_safe_batch_id: u64, - ) -> MapMapper, usize>; - - /// Mapping between Token Identifiers on Sovereign and Elrond ESDT Token Identifiers - - #[view(getSovTokenIdForElrondTokenId)] - #[storage_mapper("sovTokenIdForElrondTokenId")] - fn sov_token_id_for_elrond_token_id( - &self, - elrond_token_id: &TokenIdentifier, - ) -> SingleValueMapper; - - #[view(getElrondTokenIdForSovTokenId)] - #[storage_mapper("elrondTokenIdForSovTokenId")] - fn elrond_token_id_for_sov_token_id( - &self, - sov_token_id: &TokenIdentifier, - ) -> SingleValueMapper; - - // SC addresses - - #[view(getEsdtSafeAddress)] - #[storage_mapper("esdtSafeAddress")] - fn esdt_safe_address(&self) -> SingleValueMapper; - - #[view(getMultiTransferEsdtAddress)] - #[storage_mapper("multiTransferEsdtAddress")] - fn multi_transfer_esdt_address(&self) -> SingleValueMapper; -} diff --git a/multisig/src/user_role.rs b/multisig/src/user_role.rs deleted file mode 100644 index 813974a6..00000000 --- a/multisig/src/user_role.rs +++ /dev/null @@ -1,14 +0,0 @@ -multiversx_sc::derive_imports!(); - -#[derive(TopEncode, TopDecode, TypeAbi, Clone, Copy, PartialEq)] -pub enum UserRole { - None, - BoardMember, -} - -impl UserRole { - #[inline(always)] - pub fn is_board_member(&self) -> bool { - matches!(*self, UserRole::BoardMember) - } -} diff --git a/multisig/src/util.rs b/multisig/src/util.rs deleted file mode 100644 index b5b2a0ac..00000000 --- a/multisig/src/util.rs +++ /dev/null @@ -1,100 +0,0 @@ -multiversx_sc::imports!(); - -use transaction::{Transaction, TxAsMultiValue}; - -use crate::storage::SovBatchHash; -use crate::user_role::UserRole; - -#[multiversx_sc::module] -pub trait UtilModule: crate::storage::StorageModule { - fn get_user_role(&self, user: &ManagedAddress) -> UserRole { - let user_id = self.user_mapper().get_user_id(user); - if user_id == 0 { - UserRole::None - } else { - self.user_id_to_role(user_id).get() - } - } - - fn is_valid_action_id(&self, action_id: usize) -> bool { - let min_id = 1; - let max_id = self.action_mapper().len(); - - action_id >= min_id && action_id <= max_id - } - - fn get_all_users_with_role(&self, role: UserRole) -> MultiValueEncoded { - let mut result = ManagedVec::new(); - let num_users = self.user_mapper().get_user_count(); - for user_id in 1..=num_users { - if self.user_id_to_role(user_id).get() == role { - if let Some(address) = self.user_mapper().get_user_address(user_id) { - result.push(address); - } - } - } - result.into() - } - - fn has_enough_stake(&self, board_member_address: &ManagedAddress) -> bool { - let required_stake = self.required_stake_amount().get(); - let amount_staked = self.amount_staked(board_member_address).get(); - - amount_staked >= required_stake - } - - fn transfers_multi_value_to_sov_tx_vec( - &self, - transfers: MultiValueEncoded>, - ) -> ManagedVec> { - let mut transfers_as_sov_tx = ManagedVec::new(); - for transfer in transfers { - let transaction = Transaction::from(transfer); - - transfers_as_sov_tx.push(transaction); - } - - transfers_as_sov_tx - } - - fn require_valid_sov_tx_ids(&self, sov_tx_vec: &ManagedVec>) { - let last_executed_sov_tx_id = self.last_executed_sov_tx_id().get(); - let mut current_expected_tx_id = last_executed_sov_tx_id + 1; - - for sov_tx in sov_tx_vec { - require!(sov_tx.nonce == current_expected_tx_id, "Invalid Tx ID"); - current_expected_tx_id += 1; - } - } - - fn hash_sov_tx_batch( - &self, - sov_tx_batch: &ManagedVec>, - ) -> SovBatchHash { - let mut serialized = ManagedBuffer::new(); - if sov_tx_batch.top_encode(&mut serialized).is_err() { - sc_panic!("Failed to serialized batch"); - } - - self.crypto().keccak256(&serialized) - } - - // proxies - - #[proxy] - fn esdt_safe_proxy(&self, sc_address: ManagedAddress) -> esdt_safe::Proxy; - - #[proxy] - fn multi_transfer_esdt_proxy( - &self, - sc_address: ManagedAddress, - ) -> multi_transfer_esdt::Proxy; - - fn get_esdt_safe_proxy_instance(&self) -> esdt_safe::Proxy { - self.esdt_safe_proxy(self.esdt_safe_address().get()) - } - - fn get_multi_transfer_esdt_proxy_instance(&self) -> multi_transfer_esdt::Proxy { - self.multi_transfer_esdt_proxy(self.multi_transfer_esdt_address().get()) - } -} diff --git a/multisig/wasm/Cargo.lock b/multisig/wasm/Cargo.lock deleted file mode 100644 index 42a9ac97..00000000 --- a/multisig/wasm/Cargo.lock +++ /dev/null @@ -1,296 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "ahash" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", -] - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bridged-tokens-wrapper" -version = "0.0.0" -dependencies = [ - "multiversx-sc", - "multiversx-sc-modules", - "transaction", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "esdt-safe" -version = "0.0.0" -dependencies = [ - "max-bridged-amount-module", - "multiversx-sc", - "multiversx-sc-modules", - "token-module", - "transaction", - "tx-batch-module", -] - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-literal" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" - -[[package]] -name = "max-bridged-amount-module" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "multi-transfer-esdt" -version = "0.0.0" -dependencies = [ - "bridged-tokens-wrapper", - "max-bridged-amount-module", - "multiversx-sc", - "transaction", - "tx-batch-module", -] - -[[package]] -name = "multisig" -version = "0.0.0" -dependencies = [ - "esdt-safe", - "max-bridged-amount-module", - "multi-transfer-esdt", - "multiversx-sc", - "multiversx-sc-modules", - "token-module", - "transaction", - "tx-batch-module", -] - -[[package]] -name = "multisig-wasm" -version = "0.0.0" -dependencies = [ - "multisig", - "multiversx-sc-wasm-adapter", -] - -[[package]] -name = "multiversx-sc" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406939660d0c79dd191c6677f4b048df873a95f4531d8abafc9cdbe282bf1725" -dependencies = [ - "bitflags", - "hashbrown", - "hex-literal", - "multiversx-sc-codec", - "multiversx-sc-derive", - "num-traits", -] - -[[package]] -name = "multiversx-sc-codec" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" -dependencies = [ - "arrayvec", - "multiversx-sc-codec-derive", -] - -[[package]] -name = "multiversx-sc-codec-derive" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" -dependencies = [ - "hex", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "multiversx-sc-derive" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e006240993963b482fe0682ae49b2d07255495e3c86706925d119137376cdfc" -dependencies = [ - "hex", - "proc-macro2", - "quote", - "radix_trie", - "syn", -] - -[[package]] -name = "multiversx-sc-modules" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75dc2548fe5072cad37b5c816d2344d7cd12e8cafb1a0ff8bbf2bc1829054710" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "multiversx-sc-wasm-adapter" -version = "0.43.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40e721d1bc80de2ede4099a9040519486c3c1139cb0287d8fc4f9fc3e8a3f19e" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "proc-macro2" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "token-module" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "transaction" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "tx-batch-module" -version = "0.0.0" -dependencies = [ - "multiversx-sc", - "transaction", -] - -[[package]] -name = "unicode-ident" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/multisig/wasm/Cargo.toml b/multisig/wasm/Cargo.toml deleted file mode 100644 index f0c3ba87..00000000 --- a/multisig/wasm/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "multisig-wasm" -version = "0.0.0" -authors = ["Andrei Marinica , Dorin Iancu "] -edition = "2018" -publish = false - -[lib] -crate-type = ["cdylib"] -[profile.release] -codegen-units = 1 -opt-level = "z" -lto = true -debug = false -panic = "abort" -[dependencies.multisig] -path = ".." - -[dependencies.multiversx-sc-wasm-adapter] -version = "0.43.4" - -[workspace] -members = ["."] diff --git a/multisig/wasm/src/lib.rs b/multisig/wasm/src/lib.rs deleted file mode 100644 index 8dc79849..00000000 --- a/multisig/wasm/src/lib.rs +++ /dev/null @@ -1,85 +0,0 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. - -//////////////////////////////////////////////////// -////////////////// AUTO-GENERATED ////////////////// -//////////////////////////////////////////////////// - -// Init: 1 -// Endpoints: 57 -// Async Callback (empty): 1 -// Total number of exported functions: 59 - -#![no_std] - -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - -multiversx_sc_wasm_adapter::allocator!(); -multiversx_sc_wasm_adapter::panic_handler!(); - -multiversx_sc_wasm_adapter::endpoints! { - multisig - ( - init => init - upgrade => upgrade - stake => stake - unstake => unstake - proposeEsdtSafeSetCurrentTransactionBatchStatus => propose_esdt_safe_set_current_transaction_batch_status - proposeMultiTransferEsdtBatch => propose_multi_transfer_esdt_batch - moveRefundBatchToSafe => move_refund_batch_to_safe - performAction => perform_action_endpoint - sign => sign - upgradeChildContractFromSource => upgrade_child_contract_from_source - addBoardMember => add_board_member_endpoint - removeUser => remove_user - slashBoardMember => slash_board_member - changeQuorum => change_quorum - addMapping => add_mapping - clearMapping => clear_mapping - pauseEsdtSafe => pause_esdt_safe - unpauseEsdtSafe => unpause_esdt_safe - esdtSafeAddTokenToWhitelist => esdt_safe_add_token_to_whitelist - esdtSafeRemoveTokenFromWhitelist => esdt_safe_remove_token_from_whitelist - esdtSafeSetMaxTxBatchSize => esdt_safe_set_max_tx_batch_size - esdtSafeSetMaxTxBatchBlockDuration => esdt_safe_set_max_tx_batch_block_duration - esdtSafeSetMaxBridgedAmountForToken => esdt_safe_set_max_bridged_amount_for_token - multiTransferEsdtSetMaxBridgedAmountForToken => multi_transfer_esdt_set_max_bridged_amount_for_token - multiTransferEsdtSetMaxRefundTxBatchSize => multi_transfer_esdt_set_max_refund_tx_batch_size - multiTransferEsdtSetMaxRefundTxBatchBlockDuration => multi_transfer_esdt_set_max_refund_tx_batch_block_duration - multiTransferEsdtSetWrappingContractAddress => multi_transfer_esdt_set_wrapping_contract_address - getQuorum => quorum - getNumBoardMembers => num_board_members - getRequiredStakeAmount => required_stake_amount - getAmountStaked => amount_staked - getSlashAmount => slash_amount - getSlashedTokensAmount => slashed_tokens_amount - getLastExecutedSovBatchId => last_executed_sov_batch_id - getLastExecutedSovTxId => last_executed_sov_tx_id - getSovTokenIdForElrondTokenId => sov_token_id_for_elrond_token_id - getElrondTokenIdForSovTokenId => elrond_token_id_for_sov_token_id - getEsdtSafeAddress => esdt_safe_address - getMultiTransferEsdtAddress => multi_transfer_esdt_address - getCurrentTxBatch => get_current_tx_batch - getCurrentRefundBatch => get_current_refund_batch - wasActionExecuted => was_action_executed - wasTransferActionProposed => was_transfer_action_proposed - getActionIdForTransferBatch => get_action_id_for_transfer_batch - wasSetCurrentTransactionBatchStatusActionProposed => was_set_current_transaction_batch_status_action_proposed - getActionIdForSetCurrentTransactionBatchStatus => get_action_id_for_set_current_transaction_batch_status - signed => signed - userRole => user_role - getAllBoardMembers => get_all_board_members - getAllStakedRelayers => get_all_staked_relayers - getActionSignerCount => get_action_signer_count - getActionValidSignerCount => get_action_valid_signer_count - quorumReached => quorum_reached - getActionLastIndex => get_action_last_index - getActionData => get_action_data - pause => pause_endpoint - unpause => unpause_endpoint - isPaused => paused_status - ) -} - -multiversx_sc_wasm_adapter::async_callback_empty! {}