diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 202f45a8..6f219dd3 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -4,8 +4,11 @@ on: push: branches: - main + - feat/* pull_request: - branches: [ main ] + branches: + - main + - feat/* permissions: checks: write @@ -14,9 +17,9 @@ permissions: jobs: contracts: name: Contracts - uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v2.3.0 + uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v2.3.5 with: - rust-toolchain: nightly-2023-04-24 - vmtools-version: v1.4.60 + rust-toolchain: nightly-2023-12-11 + vmtools-version: v1.5.19 secrets: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index f9432301..7720c88c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [workspace] members = [ + "bridge-proxy", + "bridge-proxy/meta", "esdt-safe", "esdt-safe/meta", "multi-transfer-esdt", diff --git a/bridge-proxy/.gitignore b/bridge-proxy/.gitignore new file mode 100644 index 00000000..2c76bc98 --- /dev/null +++ b/bridge-proxy/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +*/target/ + +# The mxpy output +/output*/ diff --git a/bridge-proxy/Cargo.toml b/bridge-proxy/Cargo.toml new file mode 100644 index 00000000..ef15b6ad --- /dev/null +++ b/bridge-proxy/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "bridge-proxy" +version = "0.0.0" +authors = ["Costin CarabaČ™ "] +edition = "2018" +publish = false + +[lib] +path = "src/bridge-proxy.rs" + +[dependencies.transaction] +path = "../common/transaction" + +[dependencies.eth-address] +path = "../common/eth-address" + +[dependencies.multiversx-sc] +version = "0.46.1" + +[dependencies.adder] +git = "https://github.com/multiversx/mx-contracts-rs" +rev = "64e8926" + +[dev-dependencies] +num-bigint = "0.4.2" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.46.1" diff --git a/bridge-proxy/meta/Cargo.toml b/bridge-proxy/meta/Cargo.toml new file mode 100644 index 00000000..a8b29fd6 --- /dev/null +++ b/bridge-proxy/meta/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "bridge-proxy-meta" +version = "0.0.0" +edition = "2018" +publish = false +authors = ["you"] + +[dev-dependencies] + +[dependencies.bridge-proxy] +path = ".." + +[dependencies.multiversx-sc-meta] +version = "0.46.1" diff --git a/bridge-proxy/meta/src/main.rs b/bridge-proxy/meta/src/main.rs new file mode 100644 index 00000000..97b4754a --- /dev/null +++ b/bridge-proxy/meta/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + multiversx_sc_meta::cli_main::(); +} diff --git a/bridge-proxy/multiversx.json b/bridge-proxy/multiversx.json new file mode 100644 index 00000000..73655396 --- /dev/null +++ b/bridge-proxy/multiversx.json @@ -0,0 +1,3 @@ +{ + "language": "rust" +} \ No newline at end of file diff --git a/bridge-proxy/src/bridge-proxy.rs b/bridge-proxy/src/bridge-proxy.rs new file mode 100644 index 00000000..b058bacd --- /dev/null +++ b/bridge-proxy/src/bridge-proxy.rs @@ -0,0 +1,78 @@ +#![no_std] + +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +pub mod config; + +use transaction::{EthTransaction, EthTransactionPayment}; + +#[multiversx_sc::contract] +pub trait BridgeProxyContract: config::ConfigModule { + #[init] + fn init(&self, opt_multi_transfer_address: OptionalValue) { + self.set_multi_transfer_contract_address(opt_multi_transfer_address); + } + + #[payable("*")] + #[endpoint] + fn deposit(&self, eth_tx: EthTransaction) { + let (token_id, nonce, amount) = self.call_value().single_esdt().into_tuple(); + self.eth_transaction_list() + .push_back(EthTransactionPayment { + token_id, + nonce, + amount, + eth_tx, + }); + } + + #[endpoint(executeWithAsnyc)] + fn execute_with_async(&self, tx_id: u32) { + let tx_node = self + .eth_transaction_list() + .remove_node_by_id(tx_id) + .unwrap_or_else(|| sc_panic!("Invalid ETH transaction!")); + let tx = tx_node.get_value_as_ref(); + + self.send() + .contract_call::(tx.eth_tx.to.clone(), tx.eth_tx.data.clone()) + .with_raw_arguments(tx.eth_tx.args.clone().into()) + .with_esdt_transfer((tx.token_id.clone(), tx.nonce, tx.amount.clone())) + .with_gas_limit(tx.eth_tx.gas_limit) + .async_call() + .with_callback(self.callbacks().failed_execution_callback(tx)) + .call_and_exit(); + } + + #[callback] + fn failed_execution_callback(&self, tx: &EthTransactionPayment) { + self.eth_failed_transaction_list().push_back(tx.clone()); + } + + #[endpoint(refundTransactions)] + fn refund_transactions(&self) -> MultiValueEncoded> { + // Send Failed Tx Structure + let mut result = MultiValueEncoded::new(); + for tx_loop in self.eth_failed_transaction_list().iter() { + let tx = tx_loop.get_value_cloned(); + result.push(tx); + } + + // Send Funds + let mut all_payments = ManagedVec::new(); + for failed_tx_loop in self.eth_failed_transaction_list().into_iter() { + let failed_tx = failed_tx_loop.get_value_as_ref(); + + all_payments.push(EsdtTokenPayment::new( + failed_tx.token_id.clone(), + failed_tx.nonce, + failed_tx.amount.clone(), + )); + } + self.send() + .direct_multi(&self.multi_transfer_address().get(), &all_payments); + + result + } +} diff --git a/bridge-proxy/src/config.rs b/bridge-proxy/src/config.rs new file mode 100644 index 00000000..ad6f69bc --- /dev/null +++ b/bridge-proxy/src/config.rs @@ -0,0 +1,46 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use transaction::{EthTransaction, EthTransactionPayment}; + +#[multiversx_sc::module] +pub trait ConfigModule { + #[only_owner] + #[endpoint(setupMultiTransfer)] + fn set_multi_transfer_contract_address( + &self, + opt_multi_transfer_address: OptionalValue, + ) { + match opt_multi_transfer_address { + OptionalValue::Some(sc_addr) => { + require!( + self.blockchain().is_smart_contract(&sc_addr), + "Invalid multi-transfer address" + ); + self.multi_transfer_address().set(&sc_addr); + } + OptionalValue::None => self.multi_transfer_address().clear(), + } + } + + #[view(getEthTransactionById)] + fn get_eth_transaction_by_id(&self, id: u32) -> EthTransaction { + let eth_tx_list = self.eth_transaction_list(); + match eth_tx_list.get_node_by_id(id) { + Some(tx) => tx.get_value_cloned().eth_tx, + None => sc_panic!("No transaction with this id!"), + } + } + + #[view(getMultiTransferAddress)] + #[storage_mapper("multiTransferAddress")] + fn multi_transfer_address(&self) -> SingleValueMapper; + + #[view(getEthTransactionList)] + #[storage_mapper("eth_transaction_list")] + fn eth_transaction_list(&self) -> LinkedListMapper>; + + #[view(getEthFailedTransactionList)] + #[storage_mapper("eth_failed_transaction_list")] + fn eth_failed_transaction_list(&self) -> LinkedListMapper>; +} diff --git a/bridge-proxy/tests/bridge_proxy_blackbox_test.rs b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs new file mode 100644 index 00000000..9a3e1002 --- /dev/null +++ b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs @@ -0,0 +1,274 @@ +#![allow(unused)] + +use std::collections::LinkedList; + +use adder::{Adder, ProxyTrait as _}; +use bridge_proxy::config::ProxyTrait as _; +use bridge_proxy::ProxyTrait; + +use multiversx_sc::{ + api::{HandleConstraints, ManagedTypeApi}, + codec::{ + multi_types::{MultiValueVec, OptionalValue}, + TopEncodeMultiOutput, + }, + storage::mappers::SingleValue, + types::{ + Address, BigUint, CodeMetadata, ManagedAddress, ManagedArgBuffer, ManagedBuffer, + ManagedByteArray, ManagedVec, TokenIdentifier, + }, +}; +use multiversx_sc_scenario::{ + api::StaticApi, + rust_biguint, + scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}, + scenario_model::*, + ContractInfo, ScenarioWorld, +}; + +use eth_address::*; +use transaction::{EthTransaction, EthTransactionPayment}; + +const BRIDGE_TOKEN_ID: &[u8] = b"BRIDGE-123456"; +const GAS_LIMIT: u64 = 1_000_000; +const BRIDGE_PROXY_PATH_EXPR: &str = "file:output/bridge-proxy.wasm"; +const ADDER_BOGUS_PATH_EXPR: &str = "file:bogus-path.wasm"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(BRIDGE_PROXY_PATH_EXPR, bridge_proxy::ContractBuilder); + blockchain.register_contract(ADDER_BOGUS_PATH_EXPR, adder::ContractBuilder); + + blockchain +} + +type BridgeProxyContract = ContractInfo>; +type AdderContract = ContractInfo>; + +struct BridgeProxyTestState { + world: ScenarioWorld, + owner: AddressValue, + user: AddressValue, + eth_user: EthAddress, + bridge_proxy_contract: BridgeProxyContract, + adder_contract: AdderContract, +} + +impl BridgeProxyTestState { + fn setup() -> Self { + let world = world(); + let ic = &world.interpreter_context(); + + let mut state = BridgeProxyTestState { + world, + owner: "address:owner".into(), + user: "address:user".into(), + eth_user: EthAddress { + raw_addr: ManagedByteArray::default(), + }, + bridge_proxy_contract: BridgeProxyContract::new("sc:bridge_proxy"), + adder_contract: AdderContract::new("sc:adder"), + }; + + state + .world + .set_state_step(SetStateStep::new().put_account(&state.owner, Account::new().nonce(1))); + + state + } + + fn bridge_proxy_deploy(&mut self) -> &mut Self { + self.world.set_state_step( + SetStateStep::new() + .put_account(&self.owner, Account::new().nonce(1)) + .new_address(&self.owner, 1, &self.bridge_proxy_contract), + ); + + let ic = &self.world.interpreter_context(); + self.world.sc_deploy( + ScDeployStep::new() + .from(self.owner.clone()) + .code(self.world.code_expression(BRIDGE_PROXY_PATH_EXPR)) + .call(self.bridge_proxy_contract.init(ManagedAddress::zero())), + ); + + self + } + + fn deploy_adder(&mut self) -> &mut Self { + self.world.set_state_step(SetStateStep::new().new_address( + &self.owner, + 2, + &self.adder_contract, + )); + + self.world.sc_deploy( + ScDeployStep::new() + .from(self.owner.clone()) + .code(self.world.code_expression(ADDER_BOGUS_PATH_EXPR)) + .call(self.adder_contract.init(BigUint::zero())), + ); + + self + } +} + +#[test] +fn deploy_deposit_test() { + let mut test = BridgeProxyTestState::setup(); + let bridge_token_id_expr = "str:BRIDGE-123456"; // when specifying the token transfer + + test.bridge_proxy_deploy(); + test.deploy_adder(); + + let mut args = ManagedVec::new(); + args.push(ManagedBuffer::from(&[5u8])); + + let eth_tx = EthTransaction { + from: test.eth_user.clone(), + to: ManagedAddress::from_address(&test.adder_contract.to_address()), + token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID), + amount: BigUint::from(500u64), + tx_nonce: 1u64, + data: ManagedBuffer::from(b"add"), + gas_limit: GAS_LIMIT, + args, + }; + + test.world.set_state_step(SetStateStep::new().put_account( + &test.owner, + Account::new().esdt_balance(bridge_token_id_expr, 1_000u64), + )); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.deposit(ð_tx)) + .esdt_transfer(bridge_token_id_expr, 0u64, 500u64), + ); + + test.world.sc_query( + ScQueryStep::new() + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.get_eth_transaction_by_id(1u32)) + .expect_value(eth_tx), + ); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.execute_with_async(1u32)), + ); + + test.world.sc_query( + ScQueryStep::new() + .to(&test.adder_contract) + .call(test.adder_contract.sum()) + .expect_value(SingleValue::from(BigUint::from(5u32))), + ); +} + + +#[test] +fn multiple_deposit_test() { + let mut test = BridgeProxyTestState::setup(); + let bridge_token_id_expr = "str:BRIDGE-123456"; // when specifying the token transfer + + test.bridge_proxy_deploy(); + test.deploy_adder(); + + let mut args1 = ManagedVec::new(); + args1.push(ManagedBuffer::from(&[5u8])); + + let eth_tx1 = EthTransaction { + from: test.eth_user.clone(), + to: ManagedAddress::from_address(&test.adder_contract.to_address()), + token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID), + amount: BigUint::from(500u64), + tx_nonce: 1u64, + data: ManagedBuffer::from(b"add"), + gas_limit: GAS_LIMIT, + args: args1, + }; + + let mut args2 = ManagedVec::new(); + args2.push(ManagedBuffer::from(&[15u8])); + + let eth_tx2 = EthTransaction { + from: test.eth_user.clone(), + to: ManagedAddress::from_address(&test.adder_contract.to_address()), + token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID), + amount: BigUint::zero(), + tx_nonce: 1u64, + data: ManagedBuffer::from(b"add"), + gas_limit: GAS_LIMIT, + args: args2, + }; + + test.world.set_state_step(SetStateStep::new().put_account( + &test.owner, + Account::new().esdt_balance(bridge_token_id_expr, 1_000u64), + )); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.deposit(ð_tx1)) + .esdt_transfer(bridge_token_id_expr, 0u64, 500u64), + ); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.deposit(ð_tx2)) + .esdt_transfer(bridge_token_id_expr, 0u64, 0u64), + ); + + test.world.sc_query( + ScQueryStep::new() + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.get_eth_transaction_by_id(1u32)) + .expect_value(eth_tx1), + ); + + test.world.sc_query( + ScQueryStep::new() + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.get_eth_transaction_by_id(2u32)) + .expect_value(eth_tx2), + ); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.execute_with_async(1u32)), + ); + + test.world.sc_query( + ScQueryStep::new() + .to(&test.adder_contract) + .call(test.adder_contract.sum()) + .expect_value(SingleValue::from(BigUint::from(5u32))), + ); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.bridge_proxy_contract) + .call(test.bridge_proxy_contract.execute_with_async(2u32)), + ); + + test.world.sc_query( + ScQueryStep::new() + .to(&test.adder_contract) + .call(test.adder_contract.sum()) + .expect_value(SingleValue::from(BigUint::from(20u32))), + ); + +} diff --git a/bridge-proxy/wasm/Cargo.lock b/bridge-proxy/wasm/Cargo.lock new file mode 100644 index 00000000..c088f7e9 --- /dev/null +++ b/bridge-proxy/wasm/Cargo.lock @@ -0,0 +1,206 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adder" +version = "0.0.0" +source = "git+https://github.com/multiversx/mx-contracts-rs?rev=64e8926#64e892655f9c59b2aafe07800af61d0fa41c6ddc" +dependencies = [ + "multiversx-sc", +] + +[[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 = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bridge-proxy" +version = "0.0.0" +dependencies = [ + "adder", + "eth-address", + "multiversx-sc", + "transaction", +] + +[[package]] +name = "bridge-proxy-wasm" +version = "0.0.0" +dependencies = [ + "bridge-proxy", + "multiversx-sc-wasm-adapter", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "eth-address" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[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.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "multiversx-sc" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c94b173dc5ff0e157f767275fe6b7a1b4d2ad343bef7b66cd22a6353e016b93" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19908153158c03df4582af08f47c0eb39fb52a7dff4736b301a66acbbb9955d3" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b03b43f9cad320992f54ed162de2ed63e3ec83ed01361e57ee9c1865fba5a2" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b78945957036c281ad6ee21bb5120dcefa2017688adf43ec94e3e7c982efb09" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9579f40c00da56a5a68e010ff851fa48ac7b9c6a16ad4314795cb32d889d9e78" +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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +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.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "syn" +version = "2.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "transaction" +version = "0.0.0" +dependencies = [ + "eth-address", + "multiversx-sc", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/bridge-proxy/wasm/Cargo.toml b/bridge-proxy/wasm/Cargo.toml new file mode 100644 index 00000000..dc23e0bb --- /dev/null +++ b/bridge-proxy/wasm/Cargo.toml @@ -0,0 +1,31 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "bridge-proxy-wasm" +version = "0.0.0" +edition = "2018" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[dependencies.bridge-proxy] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.46.1" + +[workspace] +members = ["."] diff --git a/bridge-proxy/wasm/src/lib.rs b/bridge-proxy/wasm/src/lib.rs new file mode 100644 index 00000000..2cb3f686 --- /dev/null +++ b/bridge-proxy/wasm/src/lib.rs @@ -0,0 +1,34 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 8 +// Async Callback: 1 +// Total number of exported functions: 10 + +#![no_std] +#![allow(internal_features)] +#![feature(lang_items)] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + bridge_proxy + ( + init => init + deposit => deposit + executeWithAsnyc => execute_with_async + refundTransactions => refund_transactions + setupMultiTransfer => set_multi_transfer_contract_address + getEthTransactionById => get_eth_transaction_by_id + getMultiTransferAddress => multi_transfer_address + getEthTransactionList => eth_transaction_list + getEthFailedTransactionList => eth_failed_transaction_list + ) +} + +multiversx_sc_wasm_adapter::async_callback! { bridge_proxy } diff --git a/bridged-tokens-wrapper/Cargo.toml b/bridged-tokens-wrapper/Cargo.toml index 94e3a1f4..e2c728b2 100644 --- a/bridged-tokens-wrapper/Cargo.toml +++ b/bridged-tokens-wrapper/Cargo.toml @@ -12,10 +12,10 @@ path = "src/lib.rs" path = "../common/transaction" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" [dependencies.multiversx-sc-modules] -version = "0.45.2" +version = "0.46.1" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/bridged-tokens-wrapper/meta/Cargo.toml b/bridged-tokens-wrapper/meta/Cargo.toml index 0c7eaff8..94dedaf9 100644 --- a/bridged-tokens-wrapper/meta/Cargo.toml +++ b/bridged-tokens-wrapper/meta/Cargo.toml @@ -8,5 +8,5 @@ publish = false path = ".." [dependencies.multiversx-sc-meta] -version = "0.45.2" +version = "0.46.1" default-features = false diff --git a/bridged-tokens-wrapper/mandos/add_wrapped_token.scen.json b/bridged-tokens-wrapper/scenarios/add_wrapped_token.scen.json similarity index 100% rename from bridged-tokens-wrapper/mandos/add_wrapped_token.scen.json rename to bridged-tokens-wrapper/scenarios/add_wrapped_token.scen.json diff --git a/bridged-tokens-wrapper/mandos/blacklist_token.scen.json b/bridged-tokens-wrapper/scenarios/blacklist_token.scen.json similarity index 100% rename from bridged-tokens-wrapper/mandos/blacklist_token.scen.json rename to bridged-tokens-wrapper/scenarios/blacklist_token.scen.json diff --git a/bridged-tokens-wrapper/mandos/remove_wrapped_token.scen.json b/bridged-tokens-wrapper/scenarios/remove_wrapped_token.scen.json similarity index 100% rename from bridged-tokens-wrapper/mandos/remove_wrapped_token.scen.json rename to bridged-tokens-wrapper/scenarios/remove_wrapped_token.scen.json diff --git a/bridged-tokens-wrapper/mandos/setup.scen.json b/bridged-tokens-wrapper/scenarios/setup.scen.json similarity index 100% rename from bridged-tokens-wrapper/mandos/setup.scen.json rename to bridged-tokens-wrapper/scenarios/setup.scen.json diff --git a/bridged-tokens-wrapper/mandos/unwrap_token.scen.json b/bridged-tokens-wrapper/scenarios/unwrap_token.scen.json similarity index 100% rename from bridged-tokens-wrapper/mandos/unwrap_token.scen.json rename to bridged-tokens-wrapper/scenarios/unwrap_token.scen.json diff --git a/bridged-tokens-wrapper/mandos/whitelist_token.scen.json b/bridged-tokens-wrapper/scenarios/whitelist_token.scen.json similarity index 100% rename from bridged-tokens-wrapper/mandos/whitelist_token.scen.json rename to bridged-tokens-wrapper/scenarios/whitelist_token.scen.json diff --git a/bridged-tokens-wrapper/mandos/wrap_token.scen.json b/bridged-tokens-wrapper/scenarios/wrap_token.scen.json similarity index 100% rename from bridged-tokens-wrapper/mandos/wrap_token.scen.json rename to bridged-tokens-wrapper/scenarios/wrap_token.scen.json diff --git a/bridged-tokens-wrapper/tests/dfp_big_uint_test.rs b/bridged-tokens-wrapper/tests/dfp_big_uint_test.rs index 31a2c9b5..add8399b 100644 --- a/bridged-tokens-wrapper/tests/dfp_big_uint_test.rs +++ b/bridged-tokens-wrapper/tests/dfp_big_uint_test.rs @@ -4,7 +4,7 @@ use multiversx_sc_scenario::DebugApi; #[test] fn test_biguint() { - let _ = DebugApi::dummy(); + DebugApi::dummy(); let raw = 123456u64; let dfp = DFPBigUint::::from_raw(raw.into(), 6); let converted = dfp.clone().convert(9); @@ -12,12 +12,12 @@ fn test_biguint() { 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); + assert!(converted.convert(5).to_raw() == 12345u64); } #[test] fn test_mandos_scenario_values() { - let _ = DebugApi::dummy(); + 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/tests/scenario_go_test.rs b/bridged-tokens-wrapper/tests/scenario_go_test.rs index 4bbc4b02..a3d6e919 100644 --- a/bridged-tokens-wrapper/tests/scenario_go_test.rs +++ b/bridged-tokens-wrapper/tests/scenario_go_test.rs @@ -1,29 +1,40 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + #[test] -fn unwrap_token_go() { - multiversx_sc_scenario::run_go("mandos/unwrap_token.scen.json"); +fn add_wrapped_token_go() { + world().run("scenarios/add_wrapped_token.scen.json"); } #[test] -fn wrap_token_go() { - multiversx_sc_scenario::run_go("mandos/wrap_token.scen.json"); +fn blacklist_token_go() { + world().run("scenarios/blacklist_token.scen.json"); } #[test] -fn whitelist_token_go() { - multiversx_sc_scenario::run_go("mandos/whitelist_token.scen.json"); +fn remove_wrapped_token_go() { + world().run("scenarios/remove_wrapped_token.scen.json"); } #[test] -fn blacklist_token_go() { - multiversx_sc_scenario::run_go("mandos/blacklist_token.scen.json"); +fn setup_go() { + world().run("scenarios/setup.scen.json"); } #[test] -fn add_wrapped_token_go() { - multiversx_sc_scenario::run_go("mandos/add_wrapped_token.scen.json"); +fn unwrap_token_go() { + world().run("scenarios/unwrap_token.scen.json"); } #[test] -fn remove_wrapped_token_go() { - multiversx_sc_scenario::run_go("mandos/remove_wrapped_token.scen.json"); +fn whitelist_token_go() { + world().run("scenarios/whitelist_token.scen.json"); +} + +#[test] +fn wrap_token_go() { + world().run("scenarios/wrap_token.scen.json"); } diff --git a/bridged-tokens-wrapper/wasm/Cargo.lock b/bridged-tokens-wrapper/wasm/Cargo.lock index 26ce41ff..5cf7dda8 100644 --- a/bridged-tokens-wrapper/wasm/Cargo.lock +++ b/bridged-tokens-wrapper/wasm/Cargo.lock @@ -2,29 +2,11 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" @@ -34,9 +16,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bridged-tokens-wrapper" @@ -55,12 +37,6 @@ dependencies = [ "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" @@ -74,16 +50,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "hex" version = "0.4.3" @@ -98,12 +64,11 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2bdb196b3ff2b9f8c744ec2e026c22c8e02bc91e5c6ed09951415c47fef6b8" +checksum = "6c94b173dc5ff0e157f767275fe6b7a1b4d2ad343bef7b66cd22a6353e016b93" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", @@ -134,9 +99,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e60b5dce707f61376f74d713218f75326121d9f6a5f09a3a63de7aea2a92be9" +checksum = "3b78945957036c281ad6ee21bb5120dcefa2017688adf43ec94e3e7c982efb09" dependencies = [ "hex", "proc-macro2", @@ -147,18 +112,18 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5833f8bc88104357d38a8952d2a16c3e66080e2e512c0e7001c0c003006c475" +checksum = "c63ffaba95e630ff75981e2f5f50da64f523219b52f484234c66f3adc248885f" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4299660d5413d9f120bfddda8105b1f9d28f0345a72f53e5dc90732c4983e45" +checksum = "9579f40c00da56a5a68e010ff851fa48ac7b9c6a16ad4314795cb32d889d9e78" dependencies = [ "multiversx-sc", ] @@ -174,33 +139,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 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.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -217,15 +176,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -242,32 +201,6 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.12" 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" - -[[package]] -name = "zerocopy" -version = "0.7.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/bridged-tokens-wrapper/wasm/Cargo.toml b/bridged-tokens-wrapper/wasm/Cargo.toml index 304c40a8..c587d37a 100644 --- a/bridged-tokens-wrapper/wasm/Cargo.toml +++ b/bridged-tokens-wrapper/wasm/Cargo.toml @@ -25,7 +25,7 @@ overflow-checks = false path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.45.2" +version = "0.46.1" [workspace] members = ["."] diff --git a/bridged-tokens-wrapper/wasm/src/lib.rs b/bridged-tokens-wrapper/wasm/src/lib.rs index 61e709b7..5377fa9a 100644 --- a/bridged-tokens-wrapper/wasm/src/lib.rs +++ b/bridged-tokens-wrapper/wasm/src/lib.rs @@ -10,9 +10,7 @@ // 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. +#![allow(internal_features)] #![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); diff --git a/common/eth-address/Cargo.toml b/common/eth-address/Cargo.toml index e4b8dadc..7cf6ff45 100644 --- a/common/eth-address/Cargo.toml +++ b/common/eth-address/Cargo.toml @@ -8,4 +8,4 @@ edition = "2018" path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" diff --git a/common/eth-address/src/lib.rs b/common/eth-address/src/lib.rs index 0e4e6a53..a20ec78f 100644 --- a/common/eth-address/src/lib.rs +++ b/common/eth-address/src/lib.rs @@ -9,7 +9,9 @@ use multiversx_sc::{ pub const ETH_ADDRESS_LEN: usize = 20; /// Wrapper over a 20-byte array -#[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, Clone, ManagedVecItem)] +#[derive( + TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, Clone, ManagedVecItem, PartialEq, +)] pub struct EthAddress { pub raw_addr: ManagedByteArray, } diff --git a/common/fee-estimator-module/Cargo.toml b/common/fee-estimator-module/Cargo.toml index 88663e5d..54226945 100644 --- a/common/fee-estimator-module/Cargo.toml +++ b/common/fee-estimator-module/Cargo.toml @@ -5,7 +5,7 @@ authors = ["dorin-iancu "] edition = "2018" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/common/fee-estimator-module/src/aggregator_proxy.rs b/common/fee-estimator-module/src/aggregator_proxy.rs index 123254ae..d31ba305 100644 --- a/common/fee-estimator-module/src/aggregator_proxy.rs +++ b/common/fee-estimator-module/src/aggregator_proxy.rs @@ -3,7 +3,7 @@ multiversx_sc::imports!(); pub const GWEI_STRING: &[u8] = b"GWEI"; pub type AggregatorResultAsMultiValue = - MultiValue5, ManagedBuffer, BigUint, u8>; + MultiValue6, ManagedBuffer, u64, BigUint, u8>; #[multiversx_sc::proxy] pub trait Aggregator { @@ -19,18 +19,20 @@ pub struct AggregatorResult { pub round_id: u32, pub from_token_name: ManagedBuffer, pub to_token_name: ManagedBuffer, + pub timestamp: u64, pub price: BigUint, pub decimals: u8, } impl From> for AggregatorResult { fn from(multi_result: AggregatorResultAsMultiValue) -> Self { - let (round_id, from_token_name, to_token_name, price, decimals) = multi_result.into_tuple(); + let (round_id, from_token_name, to_token_name, timestamp, price, decimals) = multi_result.into_tuple(); AggregatorResult { round_id, from_token_name, to_token_name, + timestamp, price, decimals, } diff --git a/common/max-bridged-amount-module/Cargo.toml b/common/max-bridged-amount-module/Cargo.toml index 010ce5a2..a79eb730 100644 --- a/common/max-bridged-amount-module/Cargo.toml +++ b/common/max-bridged-amount-module/Cargo.toml @@ -5,7 +5,7 @@ authors = ["dorin-iancu "] edition = "2018" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/common/token-module/Cargo.toml b/common/token-module/Cargo.toml index 207621c7..3b85c7ce 100644 --- a/common/token-module/Cargo.toml +++ b/common/token-module/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" path = "../fee-estimator-module" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/common/token-module/src/lib.rs b/common/token-module/src/lib.rs index b1b5e3f3..3460c8bc 100644 --- a/common/token-module/src/lib.rs +++ b/common/token-module/src/lib.rs @@ -67,6 +67,7 @@ pub trait TokenModule: fee_estimator_module::FeeEstimatorModule { &self, token_id: TokenIdentifier, ticker: ManagedBuffer, + mint_burn_allowed: bool, opt_default_price_per_gas_unit: OptionalValue, ) { self.token_ticker(&token_id).set(&ticker); @@ -76,6 +77,7 @@ pub trait TokenModule: fee_estimator_module::FeeEstimatorModule { .set(&default_price_per_gas_unit); } + self.mint_burn_allowed(&token_id).set(mint_burn_allowed); let _ = self.token_whitelist().insert(token_id); } @@ -85,11 +87,56 @@ pub trait TokenModule: fee_estimator_module::FeeEstimatorModule { self.token_ticker(&token_id).clear(); self.default_price_per_gas_unit(&token_id).clear(); - let _ = self.token_whitelist().swap_remove(&token_id); + self.mint_burn_allowed(&token_id).clear(); + self.token_whitelist().swap_remove(&token_id); + } + + #[endpoint(mintToken)] + fn mint_token(&self, token_id: &TokenIdentifier, amount: &BigUint) -> EsdtTokenPayment { + let caller = self.blockchain().get_caller(); + require!( + caller == self.multi_transfer_contract_address().get(), + "Only MultiTransfer can get tokens" + ); + + if self.mint_burn_allowed(token_id).get() { + if !self + .blockchain() + .get_esdt_local_roles(token_id) + .has_role(&EsdtLocalRole::Mint) + { + return EsdtTokenPayment::new(token_id.clone(), 0, BigUint::zero()); + } + + let accumulated_burned_tokens_mapper = self.accumulated_burned_tokens(token_id); + accumulated_burned_tokens_mapper.update(|burned| { + require!(*burned >= *amount, "Not enough accumulated burned tokens!"); + *burned -= amount; + }); + self.mint_esdt_token(token_id, amount); + } + + let current_balance = + self.blockchain() + .get_esdt_balance(&self.blockchain().get_sc_address(), token_id, 0); + if ¤t_balance >= amount { + self.send().direct_esdt(&caller, token_id, 0, amount); + } else { + return EsdtTokenPayment::new(token_id.clone(), 0, BigUint::zero()); + } + EsdtTokenPayment::new(token_id.clone(), 0, amount.clone()) } // private + fn burn_esdt_token(&self, token_id: &TokenIdentifier, amount: &BigUint) { + self.send().esdt_local_burn(token_id, 0, amount); + } + + fn mint_esdt_token(&self, token_id: &TokenIdentifier, amount: &BigUint) { + self.send().esdt_local_mint(token_id, 0, amount); + } + fn require_token_in_whitelist(&self, token_id: &TokenIdentifier) { require!( self.token_whitelist().contains(token_id), @@ -110,16 +157,45 @@ pub trait TokenModule: fee_estimator_module::FeeEstimatorModule { roles.has_role(role) } + #[only_owner] + #[endpoint(setMultiTransferContractAddress)] + fn set_multi_transfer_contract_address(&self, opt_new_address: OptionalValue) { + match opt_new_address { + OptionalValue::Some(sc_addr) => { + self.multi_transfer_contract_address().set(&sc_addr); + } + OptionalValue::None => self.multi_transfer_contract_address().clear(), + } + } + + #[only_owner] + #[endpoint(setAccumulatedBurnedTokens)] + fn set_accumulated_burned_tokens(&self, token_id: &TokenIdentifier, value: BigUint) { + self.accumulated_burned_tokens(token_id).set_if_empty(value); + } + // storage #[view(getAllKnownTokens)] #[storage_mapper("tokenWhitelist")] fn token_whitelist(&self) -> UnorderedSetMapper; + #[view(isMintBurnAllowed)] + #[storage_mapper("mintBurnAllowed")] + fn mint_burn_allowed(&self, token: &TokenIdentifier) -> SingleValueMapper; + + #[view(getMultiTransferContractAddress)] + #[storage_mapper("multiTransferContractAddress")] + fn multi_transfer_contract_address(&self) -> SingleValueMapper; + #[view(getAccumulatedTransactionFees)] #[storage_mapper("accumulatedTransactionFees")] fn accumulated_transaction_fees( &self, token_id: &TokenIdentifier, ) -> SingleValueMapper; + + #[view(getAccumulatedBurnedTokens)] + #[storage_mapper("accumulatedBurnedTokens")] + fn accumulated_burned_tokens(&self, token_id: &TokenIdentifier) -> SingleValueMapper; } diff --git a/common/transaction/Cargo.toml b/common/transaction/Cargo.toml index c1f3d18c..53bc3118 100644 --- a/common/transaction/Cargo.toml +++ b/common/transaction/Cargo.toml @@ -11,4 +11,4 @@ path = "src/lib.rs" path = "../eth-address" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" diff --git a/common/transaction/src/lib.rs b/common/transaction/src/lib.rs index c2050a82..75e7892b 100644 --- a/common/transaction/src/lib.rs +++ b/common/transaction/src/lib.rs @@ -26,17 +26,36 @@ pub type TxAsMultiValue = MultiValue6< pub type PaymentsVec = ManagedVec>; pub type TxBatchSplitInFields = MultiValue2>>; -#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, ManagedVecItem, Clone)] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone, ManagedVecItem)] pub struct EthTransaction { pub from: EthAddress, pub to: ManagedAddress, pub token_id: TokenIdentifier, pub amount: BigUint, pub tx_nonce: TxNonce, + pub data: ManagedBuffer, + pub gas_limit: u64, + pub args: ManagedVec>, } -pub type EthTxAsMultiValue = - MultiValue5, ManagedAddress, TokenIdentifier, BigUint, TxNonce>; +pub type EthTxAsMultiValue = MultiValue8< + EthAddress, + ManagedAddress, + TokenIdentifier, + BigUint, + TxNonce, + ManagedBuffer, + u64, + ManagedVec>, +>; + +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)] +pub struct EthTransactionPayment { + pub token_id: TokenIdentifier, + pub nonce: u64, + pub amount: BigUint, + pub eth_tx: EthTransaction, +} #[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, ManagedVecItem, Clone)] pub struct Transaction { diff --git a/common/tx-batch-module/Cargo.toml b/common/tx-batch-module/Cargo.toml index 3d58cda8..b8a95dac 100644 --- a/common/tx-batch-module/Cargo.toml +++ b/common/tx-batch-module/Cargo.toml @@ -5,10 +5,10 @@ authors = ["dorin-iancu "] edition = "2018" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" [dependencies.transaction] path = "../transaction" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/docs/setup.md b/docs/setup.md index 01186a22..dd44c29b 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -8,7 +8,7 @@ Additionally, you will have to issue at least two ESDT tokens (suggested paramet IMPORTANT: Ticker should always be chosen so that the aggregator has a mapping for it. "WEGLD" would not work at all, since the aggregator wouldn't know about the token, but "EGLD" works perfectly) -You can find more about how to issue an ESDT token here: https://docs.elrond.com/developers/esdt-tokens/#issuance-of-fungible-esdt-tokens +You can find more about how to issue an ESDT token here: https://docs.multiversx.com/tokens/esdt-tokens/#issuance-of-fungible-esdt-tokens Next, we're going to setup the main "controller" contract, which will be a multisig-style SC. You can find more details about this type of smart contract here: https://github.com/multiversx/mx-sdk-rs/blob/master/contracts/examples/multisig/README.md @@ -35,7 +35,7 @@ The `_code` arguments are the compiled wasm bytecode of the respective contracts `esdt_safe_eth_tx_gas_limit` and `multi_transfer_esdt_eth_tx_gas_limit` are gas limits used for MultiversX -> Ethereum tx, and Ethereum -> MultiversX tx respectively. This is the gas limit used for processing on the Ethereum side (briding over to MultiversX or from MultiversX). This cost is used to calculate the fees taken from the bridged token, to be then used as payment/incentive for the relayers. -`wrapped_egld_token_id` is the token identifier of the previously issued "WrappedEgld" token (Note: identifier format is ticker + '-' + 6 random characters). For WrappedEgld, it might look something like "EGLD-123456". +`wrapped_egld_token_id` is the token identifier of the previously issued "WrappedEgld" token (Note: identifier format is ticker + '-' + 6 random characters). For WrappedEgld, it might look something like "WEGLD-123456". `token_whitelist` is a list of tokens already issued that will be used by the bridge, in our case, that will be only one: The "WrappedEth" token. diff --git a/esdt-safe/Cargo.toml b/esdt-safe/Cargo.toml index a7ce3334..62ac7441 100644 --- a/esdt-safe/Cargo.toml +++ b/esdt-safe/Cargo.toml @@ -26,11 +26,14 @@ path = "../common/tx-batch-module" [dependencies.max-bridged-amount-module] path = "../common/max-bridged-amount-module" +[dependencies.multiversx-price-aggregator-sc] +version = "0.46.1" + [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" [dependencies.multiversx-sc-modules] -version = "0.45.2" +version = "0.46.1" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/esdt-safe/interaction/snippets.sh b/esdt-safe/interaction/snippets.sh index 8a46ca3a..ec1c5148 100644 --- a/esdt-safe/interaction/snippets.sh +++ b/esdt-safe/interaction/snippets.sh @@ -1,8 +1,8 @@ -ALICE="/home/elrond/elrond-sdk/mxpy/testnet/wallets/users/alice.pem" -BOB="/home/elrond/elrond-sdk/mxpy/testnet/wallets/users/bob.pem" +ALICE="/home/multiversx/multiversx-sdk/mxpy/testnet/wallets/users/alice.pem" +BOB="/home/multiversx/multiversx-sdk/mxpy/testnet/wallets/users/bob.pem" ADDRESS=$(mxpy data load --key=address-testnet-esdt-safe) DEPLOY_TRANSACTION=$(mxpy data load --key=deployTransaction-testnet) -PROXY=https://testnet-gateway.elrond.com +PROXY=https://testnet-gateway.multiversx.com CHAIN_ID=T BOB_ADDRESS=0x8049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f8 # 32 bytes diff --git a/esdt-safe/meta/Cargo.toml b/esdt-safe/meta/Cargo.toml index 00e7a9e7..a69035ab 100644 --- a/esdt-safe/meta/Cargo.toml +++ b/esdt-safe/meta/Cargo.toml @@ -11,5 +11,5 @@ publish = false path = ".." [dependencies.multiversx-sc-meta] -version = "0.45.2" +version = "0.46.1" default-features = false diff --git a/esdt-safe/mandos/add_refund_batch.scen.json b/esdt-safe/scenarios/add_refund_batch.scen.json similarity index 98% rename from esdt-safe/mandos/add_refund_batch.scen.json rename to esdt-safe/scenarios/add_refund_batch.scen.json index c88b0013..4e749d92 100644 --- a/esdt-safe/mandos/add_refund_batch.scen.json +++ b/esdt-safe/scenarios/add_refund_batch.scen.json @@ -59,7 +59,7 @@ "str:BRIDGE-123456": { "balance": "3,001,300", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn","ESDTRoleLocalMint" ] } }, diff --git a/esdt-safe/mandos/create_another_tx_ok.scen.json b/esdt-safe/scenarios/create_another_tx_ok.scen.json similarity index 91% rename from esdt-safe/mandos/create_another_tx_ok.scen.json rename to esdt-safe/scenarios/create_another_tx_ok.scen.json index 224c9e7a..653c581b 100644 --- a/esdt-safe/mandos/create_another_tx_ok.scen.json +++ b/esdt-safe/scenarios/create_another_tx_ok.scen.json @@ -11,10 +11,12 @@ "tx": { "from": "address:user2", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:BRIDGE-123456", - "value": "1,500,900" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:BRIDGE-123456", + "value": "1,500,900" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -24,9 +26,7 @@ }, "expect": { "status": "0", - "out": [ - - ], + "out": [], "message": "", "gas": "*", "refund": "*" @@ -71,7 +71,8 @@ "str:BRIDGE-123456": { "balance": "3,001,300", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -105,4 +106,4 @@ } } ] -} +} \ No newline at end of file diff --git a/esdt-safe/mandos/create_another_tx_too_late_for_batch.scen.json b/esdt-safe/scenarios/create_another_tx_too_late_for_batch.scen.json similarity index 94% rename from esdt-safe/mandos/create_another_tx_too_late_for_batch.scen.json rename to esdt-safe/scenarios/create_another_tx_too_late_for_batch.scen.json index c9584de9..811c9c0a 100644 --- a/esdt-safe/mandos/create_another_tx_too_late_for_batch.scen.json +++ b/esdt-safe/scenarios/create_another_tx_too_late_for_batch.scen.json @@ -45,10 +45,12 @@ "tx": { "from": "address:user2", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:BRIDGE-123456", - "value": "1,500,100" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:BRIDGE-123456", + "value": "1,500,100" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -58,9 +60,7 @@ }, "expect": { "status": "0", - "out": [ - - ], + "out": [], "message": "", "gas": "*", "refund": "*" @@ -84,7 +84,8 @@ "str:BRIDGE-123456": { "balance": "4,501,400", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -176,10 +177,12 @@ "tx": { "from": "address:user3", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:BRIDGE-123456", - "value": "1,500,100" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:BRIDGE-123456", + "value": "1,500,100" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -189,9 +192,7 @@ }, "expect": { "status": "0", - "out": [ - - ], + "out": [], "message": "", "gas": "*", "refund": "*" @@ -215,7 +216,8 @@ "str:BRIDGE-123456": { "balance": "6,001,500", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -289,4 +291,4 @@ } } ] -} +} \ No newline at end of file diff --git a/esdt-safe/mandos/create_transaction_ok.scen.json b/esdt-safe/scenarios/create_transaction_ok.scen.json similarity index 91% rename from esdt-safe/mandos/create_transaction_ok.scen.json rename to esdt-safe/scenarios/create_transaction_ok.scen.json index d3e159cb..22bacf7d 100644 --- a/esdt-safe/mandos/create_transaction_ok.scen.json +++ b/esdt-safe/scenarios/create_transaction_ok.scen.json @@ -29,10 +29,12 @@ "tx": { "from": "address:user1", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:BRIDGE-123456", - "value": "1,500,400" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:BRIDGE-123456", + "value": "1,500,400" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -87,7 +89,8 @@ "str:BRIDGE-123456": { "balance": "1,500,400", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -112,4 +115,4 @@ } } ] -} +} \ No newline at end of file diff --git a/esdt-safe/mandos/create_transaction_over_max_amount.scen.json b/esdt-safe/scenarios/create_transaction_over_max_amount.scen.json similarity index 83% rename from esdt-safe/mandos/create_transaction_over_max_amount.scen.json rename to esdt-safe/scenarios/create_transaction_over_max_amount.scen.json index c76faa7f..44418d98 100644 --- a/esdt-safe/mandos/create_transaction_over_max_amount.scen.json +++ b/esdt-safe/scenarios/create_transaction_over_max_amount.scen.json @@ -33,10 +33,12 @@ "tx": { "from": "address:user1", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:BRIDGE-123456", - "value": "1,800,000" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:BRIDGE-123456", + "value": "1,800,000" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -57,10 +59,12 @@ "tx": { "from": "address:user1", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:BRIDGE-123456", - "value": "1,600,000" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:BRIDGE-123456", + "value": "1,600,000" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -70,13 +74,11 @@ }, "expect": { "status": "0", - "out": [ - - ], + "out": [], "message": "", "gas": "*", "refund": "*" } } ] -} +} \ No newline at end of file diff --git a/esdt-safe/mandos/distribute_fees.scen.json b/esdt-safe/scenarios/distribute_fees.scen.json similarity index 93% rename from esdt-safe/mandos/distribute_fees.scen.json rename to esdt-safe/scenarios/distribute_fees.scen.json index 30469112..ff0fed43 100644 --- a/esdt-safe/mandos/distribute_fees.scen.json +++ b/esdt-safe/scenarios/distribute_fees.scen.json @@ -43,9 +43,9 @@ "balance": "0", "esdt": { "str:BRIDGE-123456": { - "balance": "0", + "balance": "400", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn","ESDTRoleLocalMint" ] } }, diff --git a/esdt-safe/mandos/execute_batch_both_rejected.scen.json b/esdt-safe/scenarios/execute_batch_both_rejected.scen.json similarity index 97% rename from esdt-safe/mandos/execute_batch_both_rejected.scen.json rename to esdt-safe/scenarios/execute_batch_both_rejected.scen.json index 55d42cc2..ab8b3056 100644 --- a/esdt-safe/mandos/execute_batch_both_rejected.scen.json +++ b/esdt-safe/scenarios/execute_batch_both_rejected.scen.json @@ -97,7 +97,8 @@ "str:BRIDGE-123456": { "balance": "3,000,000", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, diff --git a/esdt-safe/mandos/execute_batch_both_success.scen.json b/esdt-safe/scenarios/execute_batch_both_success.scen.json similarity index 94% rename from esdt-safe/mandos/execute_batch_both_success.scen.json rename to esdt-safe/scenarios/execute_batch_both_success.scen.json index d8d3bdcb..f4bcfdef 100644 --- a/esdt-safe/mandos/execute_batch_both_success.scen.json +++ b/esdt-safe/scenarios/execute_batch_both_success.scen.json @@ -15,7 +15,8 @@ "function": "setTransactionBatchStatus", "arguments": [ "1", - "3", "3" + "3", + "3" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -93,9 +94,10 @@ "balance": "0", "esdt": { "str:BRIDGE-123456": { - "balance": "3,000,000", + "balance": "3,001,300", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -103,9 +105,7 @@ "str:pendingBatches|u64:1": "", "str:firstBatchId": "2", "str:lastBatchId": "2", - "str:accumulatedTransactionFees|nested:str:BRIDGE-123456": "3,000,000", - "+": "" }, "code": "file:../output/esdt-safe.wasm" @@ -114,4 +114,4 @@ } } ] -} +} \ No newline at end of file diff --git a/esdt-safe/mandos/execute_batch_one_success_one_rejected.scen.json b/esdt-safe/scenarios/execute_batch_one_success_one_rejected.scen.json similarity index 94% rename from esdt-safe/mandos/execute_batch_one_success_one_rejected.scen.json rename to esdt-safe/scenarios/execute_batch_one_success_one_rejected.scen.json index 757f5141..2244cbe0 100644 --- a/esdt-safe/mandos/execute_batch_one_success_one_rejected.scen.json +++ b/esdt-safe/scenarios/execute_batch_one_success_one_rejected.scen.json @@ -15,7 +15,8 @@ "function": "setTransactionBatchStatus", "arguments": [ "1", - "3", "4" + "3", + "4" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -94,9 +95,10 @@ "balance": "0", "esdt": { "str:BRIDGE-123456": { - "balance": "3,000,000", + "balance": "3,000,400", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -104,9 +106,7 @@ "str:pendingBatches|u64:1": "", "str:firstBatchId": "2", "str:lastBatchId": "2", - "str:accumulatedTransactionFees|nested:str:BRIDGE-123456": "3,000,000", - "+": "" }, "code": "file:../output/esdt-safe.wasm" @@ -115,4 +115,4 @@ } } ] -} +} \ No newline at end of file diff --git a/esdt-safe/mandos/execute_transaction_rejected.scen.json b/esdt-safe/scenarios/execute_transaction_rejected.scen.json similarity index 96% rename from esdt-safe/mandos/execute_transaction_rejected.scen.json rename to esdt-safe/scenarios/execute_transaction_rejected.scen.json index 52a289ac..1d61d733 100644 --- a/esdt-safe/mandos/execute_transaction_rejected.scen.json +++ b/esdt-safe/scenarios/execute_transaction_rejected.scen.json @@ -67,7 +67,8 @@ "str:BRIDGE-123456": { "balance": "1,500,000", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, diff --git a/esdt-safe/mandos/execute_transaction_success.scen.json b/esdt-safe/scenarios/execute_transaction_success.scen.json similarity index 94% rename from esdt-safe/mandos/execute_transaction_success.scen.json rename to esdt-safe/scenarios/execute_transaction_success.scen.json index 71fbb4c3..1731749b 100644 --- a/esdt-safe/mandos/execute_transaction_success.scen.json +++ b/esdt-safe/scenarios/execute_transaction_success.scen.json @@ -64,9 +64,10 @@ "balance": "0", "esdt": { "str:BRIDGE-123456": { - "balance": "1,500,000", + "balance": "1,500,400", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, diff --git a/esdt-safe/mandos/get_next_pending_tx.scen.json b/esdt-safe/scenarios/get_next_pending_tx.scen.json similarity index 100% rename from esdt-safe/mandos/get_next_pending_tx.scen.json rename to esdt-safe/scenarios/get_next_pending_tx.scen.json diff --git a/esdt-safe/mandos/get_next_tx_batch.scen.json b/esdt-safe/scenarios/get_next_tx_batch.scen.json similarity index 100% rename from esdt-safe/mandos/get_next_tx_batch.scen.json rename to esdt-safe/scenarios/get_next_tx_batch.scen.json diff --git a/esdt-safe/mandos/get_next_tx_batch_too_early.scen.json b/esdt-safe/scenarios/get_next_tx_batch_too_early.scen.json similarity index 100% rename from esdt-safe/mandos/get_next_tx_batch_too_early.scen.json rename to esdt-safe/scenarios/get_next_tx_batch_too_early.scen.json diff --git a/esdt-safe/mandos/setup_accounts.scen.json b/esdt-safe/scenarios/setup_accounts.scen.json similarity index 95% rename from esdt-safe/mandos/setup_accounts.scen.json rename to esdt-safe/scenarios/setup_accounts.scen.json index c6e77b27..2070b41a 100644 --- a/esdt-safe/mandos/setup_accounts.scen.json +++ b/esdt-safe/scenarios/setup_accounts.scen.json @@ -3,7 +3,7 @@ "steps": [ { "step": "externalSteps", - "path": "../../price-aggregator/mandos/get_latest_price_feed.scen.json" + "path": "../../price-aggregator/scenarios/get_latest_price_feed.scen.json" }, { "step": "setState", @@ -69,7 +69,8 @@ "function": "addTokenToWhitelist", "arguments": [ "str:BRIDGE-123456", - "str:BRIDGE" + "str:BRIDGE", + "true" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -135,7 +136,8 @@ "str:BRIDGE-123456": { "balance": "0", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, diff --git a/esdt-safe/mandos/zero_fees.scen.json b/esdt-safe/scenarios/zero_fees.scen.json similarity index 90% rename from esdt-safe/mandos/zero_fees.scen.json rename to esdt-safe/scenarios/zero_fees.scen.json index f5d6d36d..5e573a8c 100644 --- a/esdt-safe/mandos/zero_fees.scen.json +++ b/esdt-safe/scenarios/zero_fees.scen.json @@ -37,7 +37,8 @@ "str:BRIDGE-123456": { "balance": "0", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -56,10 +57,12 @@ "tx": { "from": "address:user1", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:BRIDGE-123456", - "value": "1,500,400" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:BRIDGE-123456", + "value": "1,500,400" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -93,7 +96,8 @@ "str:BRIDGE-123456": { "balance": "1,500,400", "roles": [ - "ESDTRoleLocalBurn" + "ESDTRoleLocalBurn", + "ESDTRoleLocalMint" ] } }, @@ -118,4 +122,4 @@ } } ] -} +} \ No newline at end of file diff --git a/esdt-safe/src/lib.rs b/esdt-safe/src/lib.rs index 5c946f68..3adf6ae8 100644 --- a/esdt-safe/src/lib.rs +++ b/esdt-safe/src/lib.rs @@ -50,7 +50,27 @@ pub trait EsdtSafe: } #[upgrade] - fn upgrade(&self) {} + fn upgrade(&self, fee_estimator_contract_address: ManagedAddress, eth_tx_gas_limit: BigUint) { + self.fee_estimator_contract_address() + .set(&fee_estimator_contract_address); + self.eth_tx_gas_limit().set(ð_tx_gas_limit); + + 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); + + // batch ID 0 is considered invalid + self.first_batch_id().set_if_empty(1); + self.last_batch_id().set_if_empty(1); + + // set ticker for "GWEI" + let gwei_token_id = TokenIdentifier::from(GWEI_STRING); + self.token_ticker(&gwei_token_id) + .set(gwei_token_id.as_managed_buffer()); + + self.set_paused(true); + } /// Sets the statuses for the transactions, after they were executed on the Ethereum side. /// @@ -87,8 +107,12 @@ pub trait EsdtSafe: // local burn role might be removed while tx is executed // tokens will remain locked forever in that case // otherwise, the whole batch would fail - if self.is_local_role_set(&tx.token_identifier, &EsdtLocalRole::Burn) { + if self.mint_burn_allowed(&tx.token_identifier).get() + && self.is_local_role_set(&tx.token_identifier, &EsdtLocalRole::Burn) + { self.burn_esdt_token(&tx.token_identifier, &tx.amount); + self.accumulated_burned_tokens(&tx.token_identifier) + .update(|burned| *burned += &tx.amount); } } TransactionStatus::Rejected => { @@ -246,10 +270,6 @@ pub trait EsdtSafe: // private - fn burn_esdt_token(&self, token_id: &TokenIdentifier, amount: &BigUint) { - self.send().esdt_local_burn(token_id, 0, amount); - } - fn mark_refund(&self, to: &ManagedAddress, token_id: &TokenIdentifier, amount: &BigUint) { self.refund_amount(to, token_id) .update(|refund| *refund += amount); diff --git a/esdt-safe/tests/esdt_safe_scenario_rs_test.rs b/esdt-safe/tests/esdt_safe_scenario_rs_test.rs new file mode 100644 index 00000000..b6a97cb3 --- /dev/null +++ b/esdt-safe/tests/esdt_safe_scenario_rs_test.rs @@ -0,0 +1,92 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + blockchain.set_current_dir_from_workspace("esdt-safe/"); + + blockchain.register_contract("file:output/esdt-safe.wasm", esdt_safe::ContractBuilder); + blockchain.register_contract("file:../price-aggregator/multiversx-price-aggregator-sc.wasm", multiversx_price_aggregator_sc::ContractBuilder); + + blockchain + +} + +#[test] +fn add_refund_batch_rs() { + world().run("scenarios/add_refund_batch.scen.json"); +} + +#[test] +fn create_another_tx_ok_rs() { + world().run("scenarios/create_another_tx_ok.scen.json"); +} + +#[test] +fn create_another_tx_too_late_for_batch_rs() { + world().run("scenarios/create_another_tx_too_late_for_batch.scen.json"); +} + +#[test] +fn create_transaction_ok_rs() { + world().run("scenarios/create_transaction_ok.scen.json"); +} + +#[test] +fn create_transaction_over_max_amount_rs() { + world().run("scenarios/create_transaction_over_max_amount.scen.json"); +} + +#[test] +fn distribute_fees_rs() { + world().run("scenarios/distribute_fees.scen.json"); +} + +#[test] +fn execute_batch_both_rejected_rs() { + world().run("scenarios/execute_batch_both_rejected.scen.json"); +} + +#[test] +fn execute_batch_both_success_rs() { + world().run("scenarios/execute_batch_both_success.scen.json"); +} + +#[test] +fn execute_batch_one_success_one_rejected_rs() { + world().run("scenarios/execute_batch_one_success_one_rejected.scen.json"); +} + +#[test] +fn execute_transaction_rejected_rs() { + world().run("scenarios/execute_transaction_rejected.scen.json"); +} + +#[test] +fn execute_transaction_success_rs() { + world().run("scenarios/execute_transaction_success.scen.json"); +} + +#[test] +fn get_next_pending_tx_rs() { + world().run("scenarios/get_next_pending_tx.scen.json"); +} + +#[test] +fn get_next_tx_batch_rs() { + world().run("scenarios/get_next_tx_batch.scen.json"); +} + +#[test] +fn get_next_tx_batch_too_early_rs() { + world().run("scenarios/get_next_tx_batch_too_early.scen.json"); +} + +#[test] +fn setup_accounts_rs() { + world().run("scenarios/setup_accounts.scen.json"); +} + +#[test] +fn zero_fees_rs() { + world().run("scenarios/zero_fees.scen.json"); +} diff --git a/esdt-safe/tests/scenario_go_test.rs b/esdt-safe/tests/scenario_go_test.rs index 205306a5..7dcd7957 100644 --- a/esdt-safe/tests/scenario_go_test.rs +++ b/esdt-safe/tests/scenario_go_test.rs @@ -1,69 +1,85 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + #[test] -fn claim_fees_go() { - multiversx_sc_scenario::run_go("mandos/distribute_fees.scen.json"); +fn add_refund_batch_go() { + world().run("scenarios/add_refund_batch.scen.json"); } #[test] fn create_another_tx_ok_go() { - multiversx_sc_scenario::run_go("mandos/create_another_tx_ok.scen.json"); + world().run("scenarios/create_another_tx_ok.scen.json"); } #[test] fn create_another_tx_too_late_for_batch_go() { - multiversx_sc_scenario::run_go("mandos/create_another_tx_too_late_for_batch.scen.json"); + world().run("scenarios/create_another_tx_too_late_for_batch.scen.json"); } #[test] fn create_transaction_ok_go() { - multiversx_sc_scenario::run_go("mandos/create_transaction_ok.scen.json"); + world().run("scenarios/create_transaction_ok.scen.json"); +} + +#[test] +fn create_transaction_over_max_amount_go() { + world().run("scenarios/create_transaction_over_max_amount.scen.json"); +} + +#[test] +fn distribute_fees_go() { + world().run("scenarios/distribute_fees.scen.json"); } #[test] fn execute_batch_both_rejected_go() { - multiversx_sc_scenario::run_go("mandos/execute_batch_both_rejected.scen.json"); + world().run("scenarios/execute_batch_both_rejected.scen.json"); } #[test] fn execute_batch_both_success_go() { - multiversx_sc_scenario::run_go("mandos/execute_batch_both_success.scen.json"); + world().run("scenarios/execute_batch_both_success.scen.json"); } #[test] fn execute_batch_one_success_one_rejected_go() { - multiversx_sc_scenario::run_go("mandos/execute_batch_one_success_one_rejected.scen.json"); + world().run("scenarios/execute_batch_one_success_one_rejected.scen.json"); } #[test] fn execute_transaction_rejected_go() { - multiversx_sc_scenario::run_go("mandos/execute_transaction_rejected.scen.json"); + world().run("scenarios/execute_transaction_rejected.scen.json"); } #[test] fn execute_transaction_success_go() { - multiversx_sc_scenario::run_go("mandos/execute_transaction_success.scen.json"); + world().run("scenarios/execute_transaction_success.scen.json"); } #[test] fn get_next_pending_tx_go() { - multiversx_sc_scenario::run_go("mandos/get_next_pending_tx.scen.json"); + world().run("scenarios/get_next_pending_tx.scen.json"); } #[test] fn get_next_tx_batch_go() { - multiversx_sc_scenario::run_go("mandos/get_next_tx_batch.scen.json"); + world().run("scenarios/get_next_tx_batch.scen.json"); } #[test] fn get_next_tx_batch_too_early_go() { - multiversx_sc_scenario::run_go("mandos/get_next_tx_batch_too_early.scen.json"); + world().run("scenarios/get_next_tx_batch_too_early.scen.json"); } #[test] fn setup_accounts_go() { - multiversx_sc_scenario::run_go("mandos/setup_accounts.scen.json"); + world().run("scenarios/setup_accounts.scen.json"); } #[test] fn zero_fees_go() { - multiversx_sc_scenario::run_go("mandos/zero_fees.scen.json"); + world().run("scenarios/zero_fees.scen.json"); } diff --git a/esdt-safe/wasm/Cargo.toml b/esdt-safe/wasm/Cargo.toml index 196a688a..4c66c1a8 100644 --- a/esdt-safe/wasm/Cargo.toml +++ b/esdt-safe/wasm/Cargo.toml @@ -25,7 +25,7 @@ overflow-checks = false path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.45.2" +version = "0.46.1" [workspace] members = ["."] diff --git a/esdt-safe/wasm/src/lib.rs b/esdt-safe/wasm/src/lib.rs index 523d1361..b3bc1203 100644 --- a/esdt-safe/wasm/src/lib.rs +++ b/esdt-safe/wasm/src/lib.rs @@ -5,14 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 32 +// Endpoints: 38 // Async Callback (empty): 1 -// Total number of exported functions: 34 +// Total number of exported functions: 40 #![no_std] - -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. +#![allow(internal_features)] #![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); @@ -39,8 +37,14 @@ multiversx_sc_wasm_adapter::endpoints! { distributeFees => distribute_fees addTokenToWhitelist => add_token_to_whitelist removeTokenFromWhitelist => remove_token_from_whitelist + mintToken => mint_token + setMultiTransferContractAddress => set_multi_transfer_contract_address + setAccumulatedBurnedTokens => set_accumulated_burned_tokens getAllKnownTokens => token_whitelist + isMintBurnAllowed => mint_burn_allowed + getMultiTransferContractAddress => multi_transfer_contract_address getAccumulatedTransactionFees => accumulated_transaction_fees + getAccumulatedBurnedTokens => accumulated_burned_tokens setMaxTxBatchSize => set_max_tx_batch_size setMaxTxBatchBlockDuration => set_max_tx_batch_block_duration getCurrentTxBatch => get_current_tx_batch diff --git a/multi-transfer-esdt/Cargo.toml b/multi-transfer-esdt/Cargo.toml index 5d50c179..3239d8a9 100644 --- a/multi-transfer-esdt/Cargo.toml +++ b/multi-transfer-esdt/Cargo.toml @@ -14,14 +14,29 @@ path = "../common/transaction" [dependencies.tx-batch-module] path = "../common/tx-batch-module" +[dependencies.eth-address] +path = "../common/eth-address" + [dependencies.max-bridged-amount-module] path = "../common/max-bridged-amount-module" [dependencies.bridged-tokens-wrapper] path = "../bridged-tokens-wrapper" +[dependencies.bridge-proxy] +path = "../bridge-proxy" + +[dependencies.esdt-safe] +path = "../esdt-safe" + +[dependencies.token-module] +path = "../common/token-module" + [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" + +[dependencies.multiversx-sc-modules] +version = "0.46.1" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/multi-transfer-esdt/README.md b/multi-transfer-esdt/README.md index 821c7653..9a3c4fb6 100644 --- a/multi-transfer-esdt/README.md +++ b/multi-transfer-esdt/README.md @@ -19,11 +19,11 @@ python3 ./interaction/playground.py --pem=./testnet/wallets/users/alice.pem --pr Deploy & interact with contract: ``` -python3 ./interaction/playground.py --pem=my.pem --proxy=https://testnet-gateway.elrond.com +python3 ./interaction/playground.py --pem=my.pem --proxy=https://testnet-gateway.multiversx.com ``` Interact with existing contract: ``` -python3 ./interaction/playground.py --pem=my.pem --proxy=https://testnet-gateway.elrond.com --contract=erd1... +python3 ./interaction/playground.py --pem=my.pem --proxy=https://testnet-gateway.multiversx.com --contract=erd1... ``` diff --git a/multi-transfer-esdt/interaction/snippets.sh b/multi-transfer-esdt/interaction/snippets.sh index 32996d89..d387f47b 100644 --- a/multi-transfer-esdt/interaction/snippets.sh +++ b/multi-transfer-esdt/interaction/snippets.sh @@ -1,8 +1,8 @@ -ALICE="/home/elrond/elrond-sdk/mxpy/testnet/wallets/users/alice.pem" -BOB="/home/elrond/elrond-sdk/mxpy/testnet/wallets/users/bob.pem" +ALICE="/home/multiversx/multiversx-sdk/mxpy/testnet/wallets/users/alice.pem" +BOB="/home/multiversx/multiversx-sdk/mxpy/testnet/wallets/users/bob.pem" ADDRESS=$(mxpy data load --key=address-testnet-multi-transfer-esdt) DEPLOY_TRANSACTION=$(mxpy data load --key=deployTransaction-testnet) -PROXY=https://testnet-gateway.elrond.com +PROXY=https://testnet-gateway.multiversx.com CHAIN_ID=T ALICE_ADDRESS=0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1 diff --git a/multi-transfer-esdt/mandos/batch_transfer_with_wrapping.scen.json b/multi-transfer-esdt/mandos/batch_transfer_with_wrapping.scen.json deleted file mode 100644 index 07bb451c..00000000 --- a/multi-transfer-esdt/mandos/batch_transfer_with_wrapping.scen.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "name": "batch transfer both executed", - "steps": [ - { - "step": "externalSteps", - "path": "../../bridged-tokens-wrapper/mandos/whitelist_token.scen.json" - }, - { - "step": "setState", - "accounts": { - "address:owner": { - "nonce": "0", - "balance": "0", - "storage": {} - }, - "address:user1": { - "nonce": "0", - "balance": "0", - "storage": {} - }, - "address:user2": { - "nonce": "0", - "balance": "0", - "storage": {} - } - }, - "newAddresses": [ - { - "creatorAddress": "address:owner", - "creatorNonce": "0", - "newAddress": "sc:multi_transfer_esdt" - } - ] - }, - { - "step": "scDeploy", - "txId": "deploy", - "tx": { - "from": "address:owner", - "contractCode": "file:../output/multi-transfer-esdt.wasm", - "value": "0", - "arguments": [], - "gasLimit": "20,000,000", - "gasPrice": "0" - }, - "expect": { - "status": "0", - "message": "", - "gas": "*", - "refund": "*" - } - }, - { - "step": "setState", - "comment": "setting local mint role", - "accounts": { - "sc:multi_transfer_esdt": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:BRIDGE-123456": { - "balance": "0", - "roles": [ - "ESDTRoleLocalMint" - ] - }, - "str:USDC-aaaaaa": { - "balance": "0", - "roles": [ - "ESDTRoleLocalMint" - ] - }, - "str:USDC-cccccc": { - "balance": "0", - "roles": [ - "ESDTRoleLocalMint" - ] - } - }, - "storage": { - "str:maxTxBatchSize": "10", - "str:maxTxBatchBlockDuration": "3,600", - "str:firstBatchId": "1", - "str:lastBatchId": "1", - "str:wrappingContractAddress": "sc:bridged_tokens_wrapper" - }, - "code": "file:../output/multi-transfer-esdt.wasm", - "owner": "address:owner" - } - } - }, - { - "step": "scCall", - "txId": "batch-transfer-both-executed", - "tx": { - "from": "address:owner", - "to": "sc:multi_transfer_esdt", - "value": "0", - "function": "batchTransferEsdtToken", - "arguments": [ - "1", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1", - "0x0102030405060708091011121314151617181920|address:user2|nested:str:USDC-aaaaaa|biguint:500|u64:2", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:USDC-cccccc|biguint:1000|u64:3" - ], - "gasLimit": "50,000,000", - "gasPrice": "0" - }, - "expect": { - "status": "0", - "message": "", - "out": "*", - "gas": "*", - "refund": "*" - } - }, - { - "step": "checkState", - "accounts": { - "address:user1": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:BRIDGE-123456": "100,200", - "str:WUSDC-abcdef": "1,000" - }, - "storage": {} - }, - "address:user2": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:WUSDC-abcdef": "500" - }, - "storage": {} - }, - "sc:bridged_tokens_wrapper": { - "nonce": "0", - "esdt": { - "str:WUSDC-abcdef": { - "balance": "1", - "roles": [ - "ESDTRoleLocalMint", - "ESDTRoleLocalBurn" - ] - }, - "str:WUSDC-uvwxyz": { - "balance": "1", - "roles": [ - "ESDTRoleLocalMint", - "ESDTRoleLocalBurn" - ] - }, - "str:USDC-aaaaaa": "500", - "str:USDC-cccccc": "1,000" - }, - "storage": "*", - "code": "*" - }, - "+": {} - } - } - ] -} diff --git a/multi-transfer-esdt/mandos/setup_accounts.scen.json b/multi-transfer-esdt/mandos/setup_accounts.scen.json deleted file mode 100644 index 37240de8..00000000 --- a/multi-transfer-esdt/mandos/setup_accounts.scen.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "name": "setup accounts", - "steps": [ - { - "step": "setState", - "accounts": { - "address:owner": { - "nonce": "0", - "balance": "0", - "storage": {} - }, - "address:user1": { - "nonce": "0", - "balance": "0", - "storage": {} - }, - "address:user2": { - "nonce": "0", - "balance": "0", - "storage": {} - } - }, - "newAddresses": [ - { - "creatorAddress": "address:owner", - "creatorNonce": "0", - "newAddress": "sc:multi_transfer_esdt" - } - ] - }, - { - "step": "scDeploy", - "txId": "deploy", - "tx": { - "from": "address:owner", - "contractCode": "file:../output/multi-transfer-esdt.wasm", - "value": "0", - "arguments": [], - "gasLimit": "20,000,000", - "gasPrice": "0" - }, - "expect": { - "status": "0", - "message": "", - "gas": "*", - "refund": "*" - } - }, - { - "step": "setState", - "comment": "setting local mint role", - "accounts": { - "sc:multi_transfer_esdt": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:BRIDGE-123456": { - "balance": "0", - "roles": [ - "ESDTRoleLocalMint" - ] - }, - "str:WRAPPED-123456": { - "balance": "0", - "roles": [ - "ESDTRoleLocalMint" - ] - } - }, - "storage": { - "str:maxTxBatchSize": "10", - "str:maxTxBatchBlockDuration": "3,600", - "str:firstBatchId": "1", - "str:lastBatchId": "1" - }, - "code": "file:../output/multi-transfer-esdt.wasm", - "owner": "address:owner" - } - } - } - ] -} diff --git a/multi-transfer-esdt/meta/Cargo.toml b/multi-transfer-esdt/meta/Cargo.toml index 7582654f..65941801 100644 --- a/multi-transfer-esdt/meta/Cargo.toml +++ b/multi-transfer-esdt/meta/Cargo.toml @@ -11,5 +11,5 @@ publish = false path = ".." [dependencies.multiversx-sc-meta] -version = "0.45.2" +version = "0.46.1" default-features = false diff --git a/multi-transfer-esdt/mandos/batch_transfer_both_executed.scen.json b/multi-transfer-esdt/scenarios/batch_transfer_both_executed.scen.json similarity index 88% rename from multi-transfer-esdt/mandos/batch_transfer_both_executed.scen.json rename to multi-transfer-esdt/scenarios/batch_transfer_both_executed.scen.json index e64ad857..c708c2bd 100644 --- a/multi-transfer-esdt/mandos/batch_transfer_both_executed.scen.json +++ b/multi-transfer-esdt/scenarios/batch_transfer_both_executed.scen.json @@ -15,8 +15,8 @@ "function": "batchTransferEsdtToken", "arguments": [ "1", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1", - "0x0102030405060708091011121314151617181920|address:user2|nested:str:WRAPPED-123456|biguint:500|u64:2" + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000|nested:0", + "0x0102030405060708091011121314151617181920|address:user2|nested:str:WRAPPED-123456|biguint:500|u64:2|nested:str:data|u64:10000000|nested:0" ], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/multi-transfer-esdt/mandos/batch_transfer_both_failed.scen.json b/multi-transfer-esdt/scenarios/batch_transfer_both_failed.scen.json similarity index 97% rename from multi-transfer-esdt/mandos/batch_transfer_both_failed.scen.json rename to multi-transfer-esdt/scenarios/batch_transfer_both_failed.scen.json index a9b34ac0..1329c6f4 100644 --- a/multi-transfer-esdt/mandos/batch_transfer_both_failed.scen.json +++ b/multi-transfer-esdt/scenarios/batch_transfer_both_failed.scen.json @@ -15,8 +15,8 @@ "function": "batchTransferEsdtToken", "arguments": [ "1", - "0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:BRIDGE-123456|biguint:100,200|u64:1", - "0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:100,500|u64:2" + "0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:2000000|nested:0", + "0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:100,500|u64:2|nested:str:data|u64:2000000|nested:0" ], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/multi-transfer-esdt/mandos/batch_transfer_one_executed_one_failed.scen.json b/multi-transfer-esdt/scenarios/batch_transfer_one_executed_one_failed.scen.json similarity index 93% rename from multi-transfer-esdt/mandos/batch_transfer_one_executed_one_failed.scen.json rename to multi-transfer-esdt/scenarios/batch_transfer_one_executed_one_failed.scen.json index 7ee4cb31..562c799e 100644 --- a/multi-transfer-esdt/mandos/batch_transfer_one_executed_one_failed.scen.json +++ b/multi-transfer-esdt/scenarios/batch_transfer_one_executed_one_failed.scen.json @@ -15,8 +15,8 @@ "function": "batchTransferEsdtToken", "arguments": [ "1", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1", - "0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:500|u64:2" + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:1000000|nested:0", + "0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:500|u64:2|nested:str:data|u64:1000000|nested:0" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -54,7 +54,6 @@ "expect": { "out": [ "1", - "0", "2", "0x0102030405060708091011121314151617181920", @@ -65,4 +64,4 @@ } } ] -} +} \ No newline at end of file diff --git a/multi-transfer-esdt/mandos/batch_transfer_to_frozen_account.scen.json b/multi-transfer-esdt/scenarios/batch_transfer_to_frozen_account.scen.json similarity index 92% rename from multi-transfer-esdt/mandos/batch_transfer_to_frozen_account.scen.json rename to multi-transfer-esdt/scenarios/batch_transfer_to_frozen_account.scen.json index 53ffbc12..9735e012 100644 --- a/multi-transfer-esdt/mandos/batch_transfer_to_frozen_account.scen.json +++ b/multi-transfer-esdt/scenarios/batch_transfer_to_frozen_account.scen.json @@ -35,8 +35,8 @@ "function": "batchTransferEsdtToken", "arguments": [ "1", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1", - "0x0102030405060708091011121314151617181920|address:frozen_user|nested:str:BRIDGE-123456|biguint:500|u64:2" + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000|nested:0", + "0x0102030405060708091011121314151617181920|address:frozen_user|nested:str:BRIDGE-123456|biguint:500|u64:2|nested:str:data|u64:10000000|nested:0" ], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/multi-transfer-esdt/scenarios/batch_transfer_with_wrapping.scen.json b/multi-transfer-esdt/scenarios/batch_transfer_with_wrapping.scen.json new file mode 100644 index 00000000..22d53384 --- /dev/null +++ b/multi-transfer-esdt/scenarios/batch_transfer_with_wrapping.scen.json @@ -0,0 +1,349 @@ +{ + "name": "batch transfer both executed", + "steps": [ + { + "step": "externalSteps", + "path": "../../bridged-tokens-wrapper/scenarios/whitelist_token.scen.json" + }, + { + "step": "setState", + "accounts": { + "address:owner": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "address:user1": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "address:user2": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "sc:esdt-safe": { + "nonce": "0", + "esdt": { + "str:BRIDGE-123456": { + "balance": "2,000,000", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + }, + "str:USDC-aaaaaa": { + "balance": "2,000,000", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + }, + "str:USDC-cccccc": { + "balance": "2,000,000", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + } + }, + "code": "file:../../esdt-safe/output/esdt-safe.wasm", + "owner": "address:owner" + } + }, + "newAddresses": [ + { + "creatorAddress": "address:owner", + "creatorNonce": "0", + "newAddress": "sc:multi_transfer_esdt" + } + ] + }, + { + "step": "scDeploy", + "txId": "deploy", + "tx": { + "from": "address:owner", + "contractCode": "file:../output/multi-transfer-esdt.wasm", + "value": "0", + "arguments": [], + "gasLimit": "20,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "setState", + "comment": "setting local mint role", + "accounts": { + "sc:multi_transfer_esdt": { + "nonce": "0", + "balance": "0", + "storage": { + "str:maxTxBatchSize": "10", + "str:maxTxBatchBlockDuration": "3,600", + "str:firstBatchId": "1", + "str:lastBatchId": "1", + "str:wrappingContractAddress": "sc:bridged_tokens_wrapper", + "str:bridgeProxyContractAddress": "sc:bridge-proxy" + }, + "code": "file:../output/multi-transfer-esdt.wasm", + "owner": "address:owner" + } + } + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "addTokenToWhitelist", + "arguments": [ + "str:BRIDGE-123456", + "str:BRIDGE", + "true", + "2,000,000" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "addTokenToWhitelist", + "arguments": [ + "str:USDC-aaaaaa", + "str:USDC", + "true", + "2,000,000" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "addTokenToWhitelist", + "arguments": [ + "str:USDC-cccccc", + "str:USDC", + "true", + "2,000,000" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-multi-transfer-contract-address", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "setMultiTransferContractAddress", + "arguments": [ + "sc:multi_transfer_esdt" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-bridge-proxy-to-multi-transfer", + "tx": { + "from": "address:owner", + "to": "sc:multi_transfer_esdt", + "function": "setEsdtSafeContractAddress", + "arguments": [ + "sc:esdt-safe" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-accumulated-burned-tokens", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "function": "setAccumulatedBurnedTokens", + "arguments": [ + "str:BRIDGE-123456", + "2,000,000" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-accumulated-burned-tokens", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "function": "setAccumulatedBurnedTokens", + "arguments": [ + "str:USDC-aaaaaa", + "500,000,000,000,000" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-accumulated-burned-tokens", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "function": "setAccumulatedBurnedTokens", + "arguments": [ + "str:USDC-cccccc", + "1,000,000,000,000,000" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "batch-transfer-both-executed", + "tx": { + "from": "address:owner", + "to": "sc:multi_transfer_esdt", + "value": "0", + "function": "batchTransferEsdtToken", + "arguments": [ + "1", + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:2000000|nested:0", + "0x0102030405060708091011121314151617181920|address:user2|nested:str:USDC-aaaaaa|biguint:500,000,000,000,000|u64:2|nested:str:data|u64:2000000|nested:0", + "0x0102030405060708091011121314151617181920|address:user1|nested:str:USDC-cccccc|biguint:1,000,000,000,000,000|u64:3|nested:str:data|u64:2000000|nested:0" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "out": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:user1": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:BRIDGE-123456": "100,200", + "str:WUSDC-abcdef": "1,000" + }, + "storage": {} + }, + "address:user2": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:WUSDC-abcdef": "500" + }, + "storage": {} + }, + "sc:bridged_tokens_wrapper": { + "nonce": "0", + "esdt": { + "str:WUSDC-abcdef": { + "balance": "1", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + }, + "str:WUSDC-uvwxyz": { + "balance": "1", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + }, + "str:USDC-aaaaaa": "500,000,000,000,000", + "str:USDC-cccccc": "1,000,000,000,000,000" + }, + "storage": "*", + "code": "*" + }, + "+": {} + } + } + ] +} \ No newline at end of file diff --git a/multi-transfer-esdt/scenarios/setup_accounts.scen.json b/multi-transfer-esdt/scenarios/setup_accounts.scen.json new file mode 100644 index 00000000..f893a190 --- /dev/null +++ b/multi-transfer-esdt/scenarios/setup_accounts.scen.json @@ -0,0 +1,333 @@ +{ + "name": "setup accounts", + "steps": [ + { + "step": "setState", + "accounts": { + "address:owner": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "address:user1": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "address:user2": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "sc:esdt-safe": { + "nonce": "0", + "esdt": { + "str:BRIDGE-123456": { + "balance": "1,000,000", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + }, + "str:WRAPPED-123456": { + "balance": "1,000,000", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + } + }, + "code": "file:../../esdt-safe/output/esdt-safe.wasm", + "owner": "address:owner" + } + }, + "newAddresses": [ + { + "creatorAddress": "address:owner", + "creatorNonce": "0", + "newAddress": "sc:multi_transfer_esdt" + }, + { + "creatorAddress": "address:owner", + "creatorNonce": "1", + "newAddress": "sc:bridge-proxy" + }, + { + "creatorAddress": "address:owner", + "creatorNonce": "2", + "newAddress": "sc:esdt-safe" + } + ] + }, + { + "step": "scDeploy", + "txId": "deploy", + "tx": { + "from": "address:owner", + "contractCode": "file:../output/multi-transfer-esdt.wasm", + "value": "0", + "arguments": [], + "gasLimit": "20,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scDeploy", + "txId": "deploy-bridge-proxy", + "tx": { + "from": "address:owner", + "contractCode": "file:../../bridge-proxy/output/bridge-proxy.wasm", + "value": "0", + "arguments": [ + "sc:multi_transfer_esdt" + ], + "gasLimit": "20,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-bridge-proxy-to-multi-transfer", + "tx": { + "from": "address:owner", + "to": "sc:multi_transfer_esdt", + "function": "setBridgeProxyContractAddress", + "arguments": [ + "sc:bridge-proxy" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "addTokenToWhitelist", + "arguments": [ + "str:BRIDGE-123456", + "str:BRIDGE", + "true", + "150,000" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "addTokenToWhitelist", + "arguments": [ + "str:WRAPPED-123456", + "str:WRAPPED", + "true", + "1,000" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-multi-transfer-contract-address", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "setMultiTransferContractAddress", + "arguments": [ + "sc:multi_transfer_esdt" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-bridge-proxy-to-multi-transfer", + "tx": { + "from": "address:owner", + "to": "sc:multi_transfer_esdt", + "function": "setEsdtSafeContractAddress", + "arguments": [ + "sc:esdt-safe" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-accumulated-burned-tokens", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "function": "setAccumulatedBurnedTokens", + "arguments": [ + "str:BRIDGE-123456", + "1_000_000" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-accumulated-burned-tokens", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "function": "setAccumulatedBurnedTokens", + "arguments": [ + "str:WRAPPED-123456", + "1_000" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:owner": { + "nonce": "9", + "balance": "0", + "storage": {} + }, + "address:user1": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "address:user2": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "sc:multi_transfer_esdt": { + "code": "file:../output/multi-transfer-esdt.wasm", + "nonce": "0", + "balance": "0", + "storage": { + "str:firstBatchId": "1", + "str:lastBatchId": "1", + "str:bridgeProxyContractAddress": "sc:bridge-proxy", + "str:maxTxBatchSize": "10", + "str:maxTxBatchBlockDuration": "0xffffffffffffffff", + "str:esdtSafeContractAddress": "sc:esdt-safe" + } + }, + "sc:bridge-proxy": { + "code": "file:../../bridge-proxy/output/bridge-proxy.wasm", + "nonce": "0", + "balance": "0", + "storage": "*" + }, + "sc:esdt-safe": { + "code": "file:../../esdt-safe/output/esdt-safe.wasm", + "nonce": "0", + "balance": "0", + "esdt": { + "str:BRIDGE-123456": { + "balance": "1,000,000", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + }, + "str:WRAPPED-123456": { + "balance": "1,000,000", + "roles": [ + "ESDTRoleLocalMint", + "ESDTRoleLocalBurn" + ] + } + }, + "storage": "*" + } + } + }, + { + "step": "setState", + "comment": "setting local mint role", + "accounts": { + "sc:multi_transfer_esdt": { + "nonce": "0", + "balance": "0", + "storage": { + "str:maxTxBatchSize": "10", + "str:maxTxBatchBlockDuration": "3,600", + "str:firstBatchId": "1", + "str:lastBatchId": "1", + "str:bridgeProxyContractAddress": "sc:bridge-proxy", + "str:esdtSafeContractAddress": "sc:esdt-safe" + }, + "code": "file:../output/multi-transfer-esdt.wasm", + "owner": "address:owner" + } + } + } + ] +} \ No newline at end of file diff --git a/multi-transfer-esdt/scenarios/transfer_fail_mint_burn_not_allowed.scen.json b/multi-transfer-esdt/scenarios/transfer_fail_mint_burn_not_allowed.scen.json new file mode 100644 index 00000000..a4db0d9f --- /dev/null +++ b/multi-transfer-esdt/scenarios/transfer_fail_mint_burn_not_allowed.scen.json @@ -0,0 +1,65 @@ +{ + "name": "transfer ok", + "steps": [ + { + "step": "externalSteps", + "path": "setup_accounts.scen.json" + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "address:owner", + "to": "sc:esdt-safe", + "value": "0", + "function": "removeTokenFromWhitelist", + "arguments": [ + "str:BRIDGE-123456" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "transfer-ok", + "tx": { + "from": "address:owner", + "to": "sc:multi_transfer_esdt", + "value": "0", + "function": "batchTransferEsdtToken", + "arguments": [ + "1", + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000|nested:0" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "out": [], + "gas": "*", + "refund": "*" + } + }, + { + "step": "scQuery", + "txId": "get-current-refund-tx-batch", + "tx": { + "to": "sc:multi_transfer_esdt", + "function": "getFirstBatchAnyStatus", + "arguments": [] + }, + "expect": { + "out": "*" + } + } + ] +} \ No newline at end of file diff --git a/multi-transfer-esdt/mandos/transfer_ok.scen.json b/multi-transfer-esdt/scenarios/transfer_ok.scen.json similarity index 92% rename from multi-transfer-esdt/mandos/transfer_ok.scen.json rename to multi-transfer-esdt/scenarios/transfer_ok.scen.json index 85911b69..2277c198 100644 --- a/multi-transfer-esdt/mandos/transfer_ok.scen.json +++ b/multi-transfer-esdt/scenarios/transfer_ok.scen.json @@ -15,7 +15,7 @@ "function": "batchTransferEsdtToken", "arguments": [ "1", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1" + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000|nested:0" ], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/multi-transfer-esdt/mandos/two_transfers_same_token.scen.json b/multi-transfer-esdt/scenarios/two_transfers_same_token.scen.json similarity index 86% rename from multi-transfer-esdt/mandos/two_transfers_same_token.scen.json rename to multi-transfer-esdt/scenarios/two_transfers_same_token.scen.json index 4799f41f..d58f4972 100644 --- a/multi-transfer-esdt/mandos/two_transfers_same_token.scen.json +++ b/multi-transfer-esdt/scenarios/two_transfers_same_token.scen.json @@ -15,8 +15,8 @@ "function": "batchTransferEsdtToken", "arguments": [ "1", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1", - "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:2" + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000|nested:0", + "0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:2|nested:str:data|u64:10000000|nested:0" ], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/multi-transfer-esdt/src/lib.rs b/multi-transfer-esdt/src/lib.rs index 43a73246..5b362caf 100644 --- a/multi-transfer-esdt/src/lib.rs +++ b/multi-transfer-esdt/src/lib.rs @@ -2,31 +2,40 @@ multiversx_sc::imports!(); -use transaction::{EthTransaction, PaymentsVec, Transaction, TxBatchSplitInFields}; +use token_module::ProxyTrait as OtherProxyTrait; +use transaction::{ + EthTransaction, EthTransactionPayment, PaymentsVec, Transaction, TxBatchSplitInFields, +}; const DEFAULT_MAX_TX_BATCH_SIZE: usize = 10; const DEFAULT_MAX_TX_BATCH_BLOCK_DURATION: u64 = u64::MAX; +const MIN_GAS_LIMIT_FOR_SC_CALL: u64 = 10_000_000; #[multiversx_sc::contract] 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); } #[upgrade] - fn upgrade(&self) {} + fn upgrade(&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); + // batch ID 0 is considered invalid + self.first_batch_id().set_if_empty(1); + self.last_batch_id().set_if_empty(1); + } #[only_owner] #[endpoint(batchTransferEsdtToken)] @@ -36,7 +45,7 @@ pub trait MultiTransferEsdt: transfers: MultiValueEncoded>, ) { let mut valid_payments_list = ManagedVec::new(); - let mut valid_dest_addresses_list = ManagedVec::new(); + let mut valid_tx_list = ManagedVec::new(); let mut refund_tx_list = ManagedVec::new(); let own_sc_address = self.blockchain().get_sc_address(); @@ -44,18 +53,19 @@ pub trait MultiTransferEsdt: for eth_tx in transfers { let mut must_refund = false; - if eth_tx.to.is_zero() || self.blockchain().is_smart_contract(ð_tx.to) { + if eth_tx.to.is_zero() { self.transfer_failed_invalid_destination(batch_id, eth_tx.tx_nonce); must_refund = true; - } else if !self.is_local_role_set(ð_tx.token_id, &EsdtLocalRole::Mint) { - self.transfer_failed_invalid_token(batch_id, eth_tx.tx_nonce); - must_refund = true; } else if self.is_above_max_amount(ð_tx.token_id, ð_tx.amount) { self.transfer_over_max_amount(batch_id, eth_tx.tx_nonce); must_refund = true; } else if self.is_account_same_shard_frozen(sc_shard, ð_tx.to, ð_tx.token_id) { self.transfer_failed_frozen_destination_account(batch_id, eth_tx.tx_nonce); must_refund = true; + } else if self.blockchain().is_smart_contract(ð_tx.to) + && (eth_tx.data.is_empty() || eth_tx.gas_limit < MIN_GAS_LIMIT_FOR_SC_CALL) + { + must_refund = true; } if must_refund { @@ -65,18 +75,27 @@ pub trait MultiTransferEsdt: continue; } - self.send() - .esdt_local_mint(ð_tx.token_id, 0, ð_tx.amount); + let minted_token: EsdtTokenPayment = self + .get_esdt_safe_contract_proxy_instance() + .mint_token(ð_tx.token_id, ð_tx.amount) + .execute_on_dest_context(); + + if minted_token.amount == BigUint::zero() { + let refund_tx = self.convert_to_refund_tx(eth_tx); + refund_tx_list.push(refund_tx); + + continue; + } // emit event before the actual transfer so we don't have to save the tx_nonces as well self.transfer_performed_event(batch_id, eth_tx.tx_nonce); - valid_dest_addresses_list.push(eth_tx.to); - valid_payments_list.push(EsdtTokenPayment::new(eth_tx.token_id, 0, eth_tx.amount)); + valid_tx_list.push(eth_tx.clone()); + valid_payments_list.push(minted_token); } let payments_after_wrapping = self.wrap_tokens(valid_payments_list); - self.distribute_payments(valid_dest_addresses_list, payments_after_wrapping); + self.distribute_payments(valid_tx_list, payments_after_wrapping); self.add_multiple_tx_to_batch(&refund_tx_list); } @@ -111,6 +130,50 @@ pub trait MultiTransferEsdt: } } + #[only_owner] + #[endpoint(setBridgeProxyContractAddress)] + fn set_bridge_proxy_contract_address(&self, opt_new_address: OptionalValue) { + match opt_new_address { + OptionalValue::Some(sc_addr) => { + require!( + self.blockchain().is_smart_contract(&sc_addr), + "Invalid bridge proxy contract address" + ); + + self.bridge_proxy_contract_address().set(&sc_addr); + } + OptionalValue::None => self.bridge_proxy_contract_address().clear(), + } + } + + #[only_owner] + #[endpoint(setEsdtSafeContractAddress)] + fn set_esdt_safe_contract_address(&self, opt_new_address: OptionalValue) { + match opt_new_address { + OptionalValue::Some(sc_addr) => { + self.esdt_safe_contract_address().set(&sc_addr); + } + OptionalValue::None => self.esdt_safe_contract_address().clear(), + } + } + + #[endpoint(getFailedTxFromBridgeProxy)] + fn get_failed_tx_from_bridge_proxy(&self) { + let mut refund_tx_list = ManagedVec::new(); + + let bridge_proxy_addr = self.bridge_proxy_contract_address().get(); + let failed_txs: MultiValueEncoded> = self + .bridge_proxy(bridge_proxy_addr) + .refund_transactions() + .execute_on_dest_context(); + + for failed_tx in failed_txs { + let refund_tx = self.convert_to_refund_tx(failed_tx.eth_tx); + refund_tx_list.push(refund_tx); + } + + self.add_multiple_tx_to_batch(&refund_tx_list); + } // private fn convert_to_refund_tx(&self, eth_tx: EthTransaction) -> Transaction { @@ -161,12 +224,20 @@ pub trait MultiTransferEsdt: fn distribute_payments( &self, - dest_addresses: ManagedVec, + transfers: ManagedVec>, payments: PaymentsVec, ) { - for (dest, p) in dest_addresses.iter().zip(payments.iter()) { - self.send() - .direct_esdt(&dest, &p.token_identifier, 0, &p.amount); + for (eth_tx, p) in transfers.iter().zip(payments.iter()) { + if self.blockchain().is_smart_contract(ð_tx.to) { + let _: IgnoreValue = self + .get_bridge_proxy_contract_proxy_instance() + .deposit(ð_tx) + .with_esdt_transfer((eth_tx.token_id.clone(), 0, eth_tx.amount.clone())) + .execute_on_dest_context(); + } else { + self.send() + .direct_esdt(ð_tx.to, &p.token_identifier, 0, &p.amount); + } } } @@ -182,12 +253,33 @@ pub trait MultiTransferEsdt: self.wrapping_contract_proxy(self.wrapping_contract_address().get()) } - // storage + #[proxy] + fn bridge_proxy(&self, sc_address: ManagedAddress) -> bridge_proxy::Proxy; + fn get_bridge_proxy_contract_proxy_instance(&self) -> bridge_proxy::Proxy { + self.bridge_proxy(self.bridge_proxy_contract_address().get()) + } + + #[proxy] + fn esdt_safe(&self, sc_address: ManagedAddress) -> esdt_safe::Proxy; + + fn get_esdt_safe_contract_proxy_instance(&self) -> esdt_safe::Proxy { + self.esdt_safe(self.esdt_safe_contract_address().get()) + } + + // storage #[view(getWrappingContractAddress)] #[storage_mapper("wrappingContractAddress")] fn wrapping_contract_address(&self) -> SingleValueMapper; + #[view(getBridgeProxyContractAddress)] + #[storage_mapper("bridgeProxyContractAddress")] + fn bridge_proxy_contract_address(&self) -> SingleValueMapper; + + #[view(getEsdtSafeContractAddress)] + #[storage_mapper("esdtSafeContractAddress")] + fn esdt_safe_contract_address(&self) -> SingleValueMapper; + // events #[event("transferPerformedEvent")] diff --git a/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs b/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs new file mode 100644 index 00000000..65e94c94 --- /dev/null +++ b/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs @@ -0,0 +1,368 @@ +#![allow(unused)] + +use bridge_proxy::{config::ProxyTrait as _, ProxyTrait as _}; +use bridged_tokens_wrapper::ProxyTrait as _; +use esdt_safe::{EsdtSafe, ProxyTrait as _}; +use multi_transfer_esdt::ProxyTrait as _; + +use multiversx_sc::{ + api::{HandleConstraints, ManagedTypeApi}, + codec::{ + multi_types::{MultiValueVec, OptionalValue}, + Empty, + }, + storage::mappers::SingleValue, + types::{ + Address, BigUint, CodeMetadata, ManagedAddress, ManagedBuffer, ManagedByteArray, + MultiValueEncoded, TokenIdentifier, ManagedVec, + }, +}; +use multiversx_sc_modules::pause::ProxyTrait; +use multiversx_sc_scenario::{ + api::{StaticApi, VMHooksApi}, + scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}, + scenario_model::*, + ContractInfo, DebugApi, ScenarioWorld, +}; + +use eth_address::*; +use token_module::ProxyTrait as _; +use transaction::{EthTransaction, EthTransactionPayment}; + +const BRIDGE_TOKEN_ID: &[u8] = b"BRIDGE-123456"; +const BRIDGE_TOKEN_ID_EXPR: &str = "str:BRIDGE-123456"; + +const USER_ETHEREUM_ADDRESS: &[u8] = b"0x0102030405060708091011121314151617181920"; + +const GAS_LIMIT: u64 = 100_000_000; + +const MULTI_TRANSFER_PATH_EXPR: &str = "file:output/multi-transfer-esdt.wasm"; +const BRIDGE_PROXY_PATH_EXPR: &str = "file:../bridge-proxy/output/bridge-proxy.wasm"; +const ESDT_SAFE_PATH_EXPR: &str = "file:../esdt-safe/output/esdt-safe.wasm"; +const BRIDGED_TOKENS_WRAPPER_PATH_EXPR: &str = + "file:../bridged-tokens-wrapper/output/bridged-tokens-wrapper.wasm"; +const PRICE_AGGREGATOR_PATH_EXPR: &str = "file:../price-aggregator/price-aggregator.wasm"; + +const MULTI_TRANSFER_ADDRESS_EXPR: &str = "sc:multi_transfer"; +const BRIDGE_PROXY_ADDRESS_EXPR: &str = "sc:bridge_proxy"; +const ESDT_SAFE_ADDRESS_EXPR: &str = "sc:esdt_safe"; +const BRIDGED_TOKENS_WRAPPER_ADDRESS_EXPR: &str = "sc:bridged_tokens_wrapper"; +const PRICE_AGGREGATOR_ADDRESS_EXPR: &str = "sc:price_aggregator"; + +const ORACLE_ADDRESS_EXPR: &str = "address:oracle"; +const OWNER_ADDRESS_EXPR: &str = "address:owner"; + +const ESDT_SAFE_ETH_TX_GAS_LIMIT: u64 = 150_000; + +const BALANCE: &str = "2,000,000"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + MULTI_TRANSFER_PATH_EXPR, + multi_transfer_esdt::ContractBuilder, + ); + blockchain.register_contract(BRIDGE_PROXY_PATH_EXPR, bridge_proxy::ContractBuilder); + + blockchain.register_contract(ESDT_SAFE_PATH_EXPR, esdt_safe::ContractBuilder); + + blockchain.register_contract( + BRIDGED_TOKENS_WRAPPER_PATH_EXPR, + bridged_tokens_wrapper::ContractBuilder, + ); + + blockchain +} + +type MultiTransferContract = ContractInfo>; +type BridgeProxyContract = ContractInfo>; +type EsdtSafeContract = ContractInfo>; +type BridgedTokensWrapperContract = ContractInfo>; + +struct MultiTransferTestState { + world: ScenarioWorld, + owner: AddressValue, + user1: AddressValue, + user2: AddressValue, + eth_user: EthAddress, + multi_transfer: MultiTransferContract, + bridge_proxy: BridgeProxyContract, + esdt_safe: EsdtSafeContract, + bridged_tokens_wrapper: BridgedTokensWrapperContract, +} + +impl MultiTransferTestState { + fn setup() -> Self { + let world = world(); + let ic = &world.interpreter_context(); + + let mut state: MultiTransferTestState = MultiTransferTestState { + world, + owner: "address:owner".into(), + user1: "address:user1".into(), + user2: "address:user2".into(), + eth_user: EthAddress { + raw_addr: ManagedByteArray::default(), + }, + multi_transfer: MultiTransferContract::new("sc:multi_transfer"), + bridge_proxy: BridgeProxyContract::new("sc:bridge_proxy"), + esdt_safe: EsdtSafeContract::new("sc:esdt_safe"), + bridged_tokens_wrapper: BridgedTokensWrapperContract::new("sc:bridged_tokens_wrapper"), + }; + + let multi_transfer_code = state.world.code_expression(MULTI_TRANSFER_PATH_EXPR); + let bridge_proxy_code = state.world.code_expression(BRIDGE_PROXY_PATH_EXPR); + let esdt_safe_code = state.world.code_expression(ESDT_SAFE_PATH_EXPR); + let bridged_tokens_wrapper_code = state + .world + .code_expression(BRIDGED_TOKENS_WRAPPER_PATH_EXPR); + + let roles = vec![ + "ESDTRoleLocalMint".to_string(), + "ESDTRoleLocalBurn".to_string(), + ]; + + state.world.set_state_step( + SetStateStep::new() + .put_account( + &state.owner, + Account::new() + .nonce(1) + .balance(BALANCE) + .esdt_balance(BRIDGE_TOKEN_ID_EXPR, BALANCE), + ) + .put_account(&state.user1, Account::new().nonce(1)) + .new_address(&state.owner, 1, MULTI_TRANSFER_ADDRESS_EXPR) + .new_address(&state.owner, 2, BRIDGE_PROXY_ADDRESS_EXPR) + .new_address(&state.owner, 3, ESDT_SAFE_ADDRESS_EXPR) + .put_account( + ESDT_SAFE_ADDRESS_EXPR, + Account::new() + .code(&esdt_safe_code) + .owner(&state.owner) + .esdt_roles(BRIDGE_TOKEN_ID_EXPR, roles) + .esdt_balance(BRIDGE_TOKEN_ID_EXPR, "1_000"), + ) + .new_address(&state.owner, 4, BRIDGED_TOKENS_WRAPPER_ADDRESS_EXPR), + ); + state + } + + fn multi_transfer_deploy(&mut self) -> &mut Self { + self.world.sc_deploy( + ScDeployStep::new() + .from(self.owner.clone()) + .code(self.world.code_expression(MULTI_TRANSFER_PATH_EXPR)) + .call(self.multi_transfer.init()), + ); + + self + } + + fn bridge_proxy_deploy(&mut self) -> &mut Self { + self.world.sc_deploy( + ScDeployStep::new() + .from(self.owner.clone()) + .code(self.world.code_expression(BRIDGE_PROXY_PATH_EXPR)) + .call(self.bridge_proxy.init(self.multi_transfer.to_address())), + ); + + self + } + + fn safe_deploy(&mut self, price_aggregator_contract_address: Address) -> &mut Self { + self.world.sc_call( + ScCallStep::new().from(self.owner.clone()).call( + self.esdt_safe + .upgrade(ManagedAddress::zero(), ESDT_SAFE_ETH_TX_GAS_LIMIT), + ), + ); + + self + } + + fn bridged_tokens_wrapper_deploy(&mut self) -> &mut Self { + self.world.sc_deploy( + ScDeployStep::new() + .from(self.owner.clone()) + .code(self.world.code_expression(BRIDGED_TOKENS_WRAPPER_PATH_EXPR)) + .call(self.bridged_tokens_wrapper.init()), + ); + + self + } + + fn config_multi_transfer(&mut self) { + self.world + .sc_call( + ScCallStep::new() + .from(self.owner.clone()) + .to(&self.multi_transfer) + .call( + self.multi_transfer.set_wrapping_contract_address( + self.bridged_tokens_wrapper.to_address(), + ), + ), + ) + .sc_call( + ScCallStep::new() + .from(self.owner.clone()) + .to(&self.multi_transfer) + .call( + self.multi_transfer + .set_bridge_proxy_contract_address(self.bridge_proxy.to_address()), + ), + ) + .sc_call( + ScCallStep::new() + .from(self.owner.clone()) + .to(&self.multi_transfer) + .call( + self.multi_transfer + .set_esdt_safe_contract_address(self.esdt_safe.to_address()), + ), + ) + .sc_call( + ScCallStep::new() + .from(self.owner.clone()) + .to(&self.esdt_safe) + .call( + self.esdt_safe + .set_multi_transfer_contract_address(self.multi_transfer.to_address()), + ), + ) + .sc_call( + ScCallStep::new() + .from(self.owner.clone()) + .to(&self.esdt_safe) + .call(self.esdt_safe.add_token_to_whitelist( + TokenIdentifier::from_esdt_bytes("BRIDGE-123456"), + "BRIDGE", + true, + BigUint::from(ESDT_SAFE_ETH_TX_GAS_LIMIT), + )), + ) + .sc_call( + ScCallStep::new() + .from(self.owner.clone()) + .to(&self.esdt_safe) + .call(self.esdt_safe.set_accumulated_burned_tokens( + TokenIdentifier::from_esdt_bytes("BRIDGE-123456"), + BigUint::from(1_000u64), + )), + ); + } +} + +#[test] +fn basic_setup_test() { + let mut test: MultiTransferTestState = MultiTransferTestState::setup(); + let bridge_token_id_expr = "str:BRIDGE-123456"; // when specifying the token transfer + + test.multi_transfer_deploy(); + test.bridge_proxy_deploy(); + test.safe_deploy(Address::zero()); + test.bridged_tokens_wrapper_deploy(); + test.config_multi_transfer(); + + test.world.set_state_step(SetStateStep::new().put_account( + &test.owner, + Account::new().esdt_balance(bridge_token_id_expr, 1_000u64), + )); + + let eth_tx = EthTransaction { + from: test.eth_user, + to: ManagedAddress::from_address(&test.user1.value), + token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID), + amount: BigUint::from(500u64), + tx_nonce: 1u64, + data: ManagedBuffer::from("data"), + gas_limit: GAS_LIMIT, + args: ManagedVec::new() + }; + + test.world.check_state_step( + CheckStateStep::new().put_account( + &test.multi_transfer, + CheckAccount::new() + .check_storage("str:bridgeProxyContractAddress", "sc:bridge_proxy") + .check_storage("str:lastBatchId", "0x01") + .check_storage("str:wrappingContractAddress", "sc:bridged_tokens_wrapper") + .check_storage("str:maxTxBatchBlockDuration", "0xffffffffffffffff") + .check_storage("str:maxTxBatchSize", "10") + .check_storage("str:firstBatchId", "0x01") + .check_storage("str:esdtSafeContractAddress", "sc:esdt_safe"), + ), + ); +} + +#[test] +fn basic_transfer_test() { + let mut test: MultiTransferTestState = MultiTransferTestState::setup(); + let token_amount = BigUint::from(500u64); + + test.multi_transfer_deploy(); + test.bridge_proxy_deploy(); + test.safe_deploy(Address::zero()); + test.bridged_tokens_wrapper_deploy(); + test.config_multi_transfer(); + + let eth_tx = EthTransaction { + from: test.eth_user, + to: ManagedAddress::from_address(&test.user1.value), + token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID), + amount: token_amount.clone(), + tx_nonce: 1u64, + data: ManagedBuffer::from("data"), + gas_limit: GAS_LIMIT, + args: ManagedVec::new() + }; + + test.world.check_state_step( + CheckStateStep::new().put_account( + &test.multi_transfer, + CheckAccount::new() + .check_storage("str:bridgeProxyContractAddress", "sc:bridge_proxy") + .check_storage("str:lastBatchId", "0x01") + .check_storage("str:wrappingContractAddress", "sc:bridged_tokens_wrapper") + .check_storage("str:maxTxBatchBlockDuration", "0xffffffffffffffff") + .check_storage("str:maxTxBatchSize", "10") + .check_storage("str:firstBatchId", "0x01") + .check_storage("str:esdtSafeContractAddress", "sc:esdt_safe"), + ), + ); + + let mut transfers = MultiValueEncoded::new(); + transfers.push(eth_tx); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.esdt_safe) + .call(test.esdt_safe.unpause_endpoint()), + ); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.bridged_tokens_wrapper) + .call(test.bridged_tokens_wrapper.unpause_endpoint()), + ); + + test.world.sc_call( + ScCallStep::new() + .from(&test.owner) + .to(&test.multi_transfer) + .call( + test.multi_transfer + .batch_transfer_esdt_token(1u32, transfers), + ), + ); + + test.world + .check_state_step(CheckStateStep::new().put_account( + test.user1, + CheckAccount::new().esdt_balance(BRIDGE_TOKEN_ID_EXPR, token_amount), + )); +} diff --git a/multi-transfer-esdt/tests/multi_transfer_esdt_scenario_rs_test.rs b/multi-transfer-esdt/tests/multi_transfer_esdt_scenario_rs_test.rs new file mode 100644 index 00000000..602df64f --- /dev/null +++ b/multi-transfer-esdt/tests/multi_transfer_esdt_scenario_rs_test.rs @@ -0,0 +1,58 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + blockchain.set_current_dir_from_workspace("multi-transfer-esdt/"); + + blockchain.register_contract("file:output/multi-transfer-esdt.wasm", multi_transfer_esdt::ContractBuilder); + blockchain.register_contract("file:../esdt-safe/output/esdt-safe.wasm", esdt_safe::ContractBuilder); + blockchain.register_contract("file:../bridge-proxy/output/bridge-proxy.wasm", bridge_proxy::ContractBuilder); + blockchain.register_contract("file:../bridged-tokens-wrapper/output/bridged-tokens-wrapper.wasm", bridged_tokens_wrapper::ContractBuilder); + + blockchain +} + +#[test] +fn batch_transfer_both_executed_rs() { + world().run("scenarios/batch_transfer_both_executed.scen.json"); +} + +#[test] +fn batch_transfer_both_failed_rs() { + world().run("scenarios/batch_transfer_both_failed.scen.json"); +} + +#[test] +fn batch_transfer_one_executed_one_failed_rs() { + world().run("scenarios/batch_transfer_one_executed_one_failed.scen.json"); +} + +#[test] +fn batch_transfer_to_frozen_account_rs() { + world().run("scenarios/batch_transfer_to_frozen_account.scen.json"); +} + +#[test] +fn batch_transfer_with_wrapping_rs() { + world().run("scenarios/batch_transfer_with_wrapping.scen.json"); +} + +#[test] +fn setup_accounts_rs() { + world().run("scenarios/setup_accounts.scen.json"); +} + +#[test] +fn transfer_fail_mint_burn_not_allowed_rs() { + world().run("scenarios/transfer_fail_mint_burn_not_allowed.scen.json"); +} + +#[test] +fn transfer_ok_rs() { + world().run("scenarios/transfer_ok.scen.json"); +} + +#[test] +fn two_transfers_same_token_rs() { + world().run("scenarios/two_transfers_same_token.scen.json"); +} diff --git a/multi-transfer-esdt/tests/scenario_go_test.rs b/multi-transfer-esdt/tests/scenario_go_test.rs index cdda9c2b..b58db004 100644 --- a/multi-transfer-esdt/tests/scenario_go_test.rs +++ b/multi-transfer-esdt/tests/scenario_go_test.rs @@ -1,34 +1,50 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + #[test] fn batch_transfer_both_executed_go() { - multiversx_sc_scenario::run_go("mandos/batch_transfer_both_executed.scen.json"); + world().run("scenarios/batch_transfer_both_executed.scen.json"); } #[test] fn batch_transfer_both_failed_go() { - multiversx_sc_scenario::run_go("mandos/batch_transfer_both_failed.scen.json"); + world().run("scenarios/batch_transfer_both_failed.scen.json"); } #[test] fn batch_transfer_one_executed_one_failed_go() { - multiversx_sc_scenario::run_go("mandos/batch_transfer_one_executed_one_failed.scen.json"); + world().run("scenarios/batch_transfer_one_executed_one_failed.scen.json"); } #[test] fn batch_transfer_to_frozen_account_go() { - multiversx_sc_scenario::run_go("mandos/batch_transfer_to_frozen_account.scen.json"); + world().run("scenarios/batch_transfer_to_frozen_account.scen.json"); +} + +#[test] +fn batch_transfer_with_wrapping_go() { + world().run("scenarios/batch_transfer_with_wrapping.scen.json"); } #[test] fn setup_accounts_go() { - multiversx_sc_scenario::run_go("mandos/setup_accounts.scen.json"); + world().run("scenarios/setup_accounts.scen.json"); +} + +#[test] +fn transfer_fail_mint_burn_not_allowed_go() { + world().run("scenarios/transfer_fail_mint_burn_not_allowed.scen.json"); } #[test] fn transfer_ok_go() { - multiversx_sc_scenario::run_go("mandos/transfer_ok.scen.json"); + world().run("scenarios/transfer_ok.scen.json"); } #[test] fn two_transfers_same_token_go() { - multiversx_sc_scenario::run_go("mandos/two_transfers_same_token.scen.json"); + world().run("scenarios/two_transfers_same_token.scen.json"); } diff --git a/multi-transfer-esdt/wasm/Cargo.lock b/multi-transfer-esdt/wasm/Cargo.lock index a6f561a9..1dfb2b05 100644 --- a/multi-transfer-esdt/wasm/Cargo.lock +++ b/multi-transfer-esdt/wasm/Cargo.lock @@ -3,23 +3,13 @@ version = 3 [[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +name = "adder" +version = "0.0.0" +source = "git+https://github.com/multiversx/mx-contracts-rs?rev=64e8926#64e892655f9c59b2aafe07800af61d0fa41c6ddc" dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", + "multiversx-sc", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" version = "0.7.4" @@ -34,9 +24,19 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "bridge-proxy" +version = "0.0.0" +dependencies = [ + "adder", + "eth-address", + "multiversx-sc", + "transaction", +] [[package]] name = "bridged-tokens-wrapper" @@ -47,6 +47,12 @@ dependencies = [ "transaction", ] +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "cfg-if" version = "1.0.0" @@ -59,6 +65,21 @@ 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 = [ + "eth-address", + "fee-estimator-module", + "max-bridged-amount-module", + "multiversx-price-aggregator-sc", + "multiversx-sc", + "multiversx-sc-modules", + "token-module", + "transaction", + "tx-batch-module", +] + [[package]] name = "eth-address" version = "0.0.0" @@ -67,13 +88,23 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.14.3" +name = "fee-estimator-module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "getrandom" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ - "ahash", - "allocator-api2", + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", ] [[package]] @@ -88,6 +119,27 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "max-bridged-amount-module" version = "0.0.0" @@ -99,9 +151,14 @@ dependencies = [ name = "multi-transfer-esdt" version = "0.0.0" dependencies = [ + "bridge-proxy", "bridged-tokens-wrapper", + "esdt-safe", + "eth-address", "max-bridged-amount-module", "multiversx-sc", + "multiversx-sc-modules", + "token-module", "transaction", "tx-batch-module", ] @@ -114,14 +171,26 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] +[[package]] +name = "multiversx-price-aggregator-sc" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8de03c6796bd16c39cafafd13da688d9f64d30965866d1c0d0badd2071235f9" +dependencies = [ + "arrayvec", + "getrandom", + "multiversx-sc", + "multiversx-sc-modules", + "rand", +] + [[package]] name = "multiversx-sc" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2bdb196b3ff2b9f8c744ec2e026c22c8e02bc91e5c6ed09951415c47fef6b8" +checksum = "6c94b173dc5ff0e157f767275fe6b7a1b4d2ad343bef7b66cd22a6353e016b93" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", @@ -152,9 +221,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e60b5dce707f61376f74d713218f75326121d9f6a5f09a3a63de7aea2a92be9" +checksum = "3b78945957036c281ad6ee21bb5120dcefa2017688adf43ec94e3e7c982efb09" dependencies = [ "hex", "proc-macro2", @@ -165,18 +234,18 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5833f8bc88104357d38a8952d2a16c3e66080e2e512c0e7001c0c003006c475" +checksum = "c63ffaba95e630ff75981e2f5f50da64f523219b52f484234c66f3adc248885f" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4299660d5413d9f120bfddda8105b1f9d28f0345a72f53e5dc90732c4983e45" +checksum = "9579f40c00da56a5a68e010ff851fa48ac7b9c6a16ad4314795cb32d889d9e78" dependencies = [ "multiversx-sc", ] @@ -192,33 +261,39 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -233,23 +308,61 @@ dependencies = [ "nibble_vec", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "token-module" +version = "0.0.0" +dependencies = [ + "fee-estimator-module", + "multiversx-sc", +] + [[package]] name = "transaction" version = "0.0.0" @@ -268,32 +381,66 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "zerocopy" -version = "0.7.31" +name = "wasm-bindgen" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ - "zerocopy-derive", + "cfg-if", + "wasm-bindgen-macro", ] [[package]] -name = "zerocopy-derive" -version = "0.7.31" +name = "wasm-bindgen-backend" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ + "bumpalo", + "log", + "once_cell", "proc-macro2", "quote", "syn", + "wasm-bindgen-shared", ] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" diff --git a/multi-transfer-esdt/wasm/Cargo.toml b/multi-transfer-esdt/wasm/Cargo.toml index 69f59530..66b222ea 100644 --- a/multi-transfer-esdt/wasm/Cargo.toml +++ b/multi-transfer-esdt/wasm/Cargo.toml @@ -25,7 +25,7 @@ overflow-checks = false path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.45.2" +version = "0.46.1" [workspace] members = ["."] diff --git a/multi-transfer-esdt/wasm/src/lib.rs b/multi-transfer-esdt/wasm/src/lib.rs index 85514113..bec1d596 100644 --- a/multi-transfer-esdt/wasm/src/lib.rs +++ b/multi-transfer-esdt/wasm/src/lib.rs @@ -5,14 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 15 +// Endpoints: 20 // Async Callback (empty): 1 -// Total number of exported functions: 17 +// Total number of exported functions: 22 #![no_std] - -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. +#![allow(internal_features)] #![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); @@ -26,7 +24,12 @@ multiversx_sc_wasm_adapter::endpoints! { batchTransferEsdtToken => batch_transfer_esdt_token getAndClearFirstRefundBatch => get_and_clear_first_refund_batch setWrappingContractAddress => set_wrapping_contract_address + setBridgeProxyContractAddress => set_bridge_proxy_contract_address + setEsdtSafeContractAddress => set_esdt_safe_contract_address + getFailedTxFromBridgeProxy => get_failed_tx_from_bridge_proxy getWrappingContractAddress => wrapping_contract_address + getBridgeProxyContractAddress => bridge_proxy_contract_address + getEsdtSafeContractAddress => esdt_safe_contract_address setMaxTxBatchSize => set_max_tx_batch_size setMaxTxBatchBlockDuration => set_max_tx_batch_block_duration getCurrentTxBatch => get_current_tx_batch diff --git a/multisig/Cargo.toml b/multisig/Cargo.toml index d6f77141..c2d6287d 100644 --- a/multisig/Cargo.toml +++ b/multisig/Cargo.toml @@ -33,10 +33,13 @@ path = "../esdt-safe" path = "../multi-transfer-esdt" [dependencies.multiversx-sc] -version = "0.45.2" +version = "0.46.1" + +[dependencies.multiversx-price-aggregator-sc] +version = "0.46.1" [dependencies.multiversx-sc-modules] -version = "0.45.2" +version = "0.46.1" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.2" +version = "0.46.1" diff --git a/multisig/interaction/config/configs.cfg b/multisig/interaction/config/configs.cfg index 9b58c555..d72fa513 100644 --- a/multisig/interaction/config/configs.cfg +++ b/multisig/interaction/config/configs.cfg @@ -17,6 +17,7 @@ SAFE_WASM="./esdt-safe.wasm" BRIDGED_TOKENS_WRAPPER_WASM="./bridged-tokens-wrapper.wasm" MULTI_TRANSFER_WASM="./multi-transfer-esdt.wasm" MULTISIG_WASM="./multisig.wasm" +PROXY_WASM="./bridge-proxy.wasm" #============CONTRACT ADDRESSES============== @@ -38,10 +39,10 @@ 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 - +UNIVERSAL_TOKEN= +CHAIN_SPECIFIC_TOKEN=MEX-a659d0 +ERC20_TOKEN=0x2E8e0BBe20Ecd819c721D164fb91F7c33BDFC756 +MINTBURN_WHITELIST=true #============BRIDGE SETTINGS============== FEE_AMOUNT=50 # value without decimals diff --git a/multisig/interaction/config/menu_functions.cfg b/multisig/interaction/config/menu_functions.cfg index e7585ccf..90fd5da7 100644 --- a/multisig/interaction/config/menu_functions.cfg +++ b/multisig/interaction/config/menu_functions.cfg @@ -5,6 +5,7 @@ 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/proxy-snippets.sh source $SCRIPTPATH/config/relayers-snippets.sh source $SCRIPTPATH/config/upgrade-snippets.sh source $SCRIPTPATH/config/wrapped-snippets.sh @@ -39,14 +40,17 @@ function upgrade-wrapper-chain-specific-token { } function deploy-bridge-contracts { - deploySafe - update-config SAFE ${ADDRESS} + confirmation-with-skip deploySafe confirmation-with-skip deployMultiTransfer - update-config MULTI_TRANSFER ${ADDRESS} confirmation-with-skip deployMultisig - update-config MULTISIG ${ADDRESS} + confirmation-with-skip deployBridgeProxy + confirmation-with-skip setBridgeProxyContractAddress + confirmation-with-skip setWrappingContractAddress confirmation-with-skip changeChildContractsOwnershipSafe confirmation-with-skip changeChildContractsOwnershipMultiTransfer + confirmation-with-skip changeChildContractsOwnershipProxy + confirmation-with-skip setMultiTransferOnEsdtSafe + confirmation-with-skip setEsdtSafeOnMultiTransfer } function remove-whitelist-token { @@ -84,7 +88,21 @@ function whitelist-token { 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 whitelist-native-token { + confirmation-with-skip setLocalRolesEsdtSafe confirmation-with-skip addMapping confirmation-with-skip addTokenToWhitelist echo -e diff --git a/multisig/interaction/config/multisig-snippets.sh b/multisig/interaction/config/multisig-snippets.sh index 2037bfc1..2cc6db27 100644 --- a/multisig/interaction/config/multisig-snippets.sh +++ b/multisig/interaction/config/multisig-snippets.sh @@ -19,6 +19,7 @@ deployMultisig() { echo "" echo "Multisig contract address: ${ADDRESS}" + update-config MULTISIG ${ADDRESS} } changeChildContractsOwnershipSafe() { @@ -30,6 +31,15 @@ changeChildContractsOwnershipSafe() { --send --proxy=${PROXY} --chain=${CHAIN_ID} } +changeChildContractsOwnershipProxy() { + CHECK_VARIABLES BRIDGE_PROXY MULTISIG + + mxpy --verbose contract call ${BRIDGE_PROXY} --recall-nonce --pem=${ALICE} \ + --gas-limit=10000000 --function="ChangeOwnerAddress" \ + --arguments ${MULTISIG} \ + --send --proxy=${PROXY} --chain=${CHAIN_ID} +} + changeChildContractsOwnershipMultiTransfer() { CHECK_VARIABLES MULTI_TRANSFER MULTISIG @@ -58,11 +68,11 @@ addMapping() { } addTokenToWhitelist() { - CHECK_VARIABLES CHAIN_SPECIFIC_TOKEN CHAIN_SPECIFIC_TOKEN_TICKER MULTISIG + CHECK_VARIABLES CHAIN_SPECIFIC_TOKEN CHAIN_SPECIFIC_TOKEN_TICKER MULTISIG MINTBURN_WHITELIST mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ --gas-limit=60000000 --function="esdtSafeAddTokenToWhitelist" \ - --arguments str:${CHAIN_SPECIFIC_TOKEN} str:${CHAIN_SPECIFIC_TOKEN_TICKER} \ + --arguments str:${CHAIN_SPECIFIC_TOKEN} str:${CHAIN_SPECIFIC_TOKEN_TICKER} ${MINTBURN_WHITELIST} \ --send --proxy=${PROXY} --chain=${CHAIN_ID} } @@ -162,3 +172,20 @@ multiTransferEsdtSetMaxBridgedAmountForToken() { --arguments str:${CHAIN_SPECIFIC_TOKEN} ${MAX} \ --send --proxy=${PROXY} --chain=${CHAIN_ID} } + + +setMultiTransferOnEsdtSafe() { + CHECK_VARIABLES MULTISIG + + mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ + --gas-limit=60000000 --function="setMultiTransferOnEsdtSafe" \ + --send --proxy=${PROXY} --chain=${CHAIN_ID} +} + +setEsdtSafeOnMultiTransfer() { + CHECK_VARIABLES MULTISIG + + mxpy --verbose contract call ${MULTISIG} --recall-nonce --pem=${ALICE} \ + --gas-limit=60000000 --function="setEsdtSafeOnMultiTransfer" \ + --send --proxy=${PROXY} --chain=${CHAIN_ID} +} \ No newline at end of file diff --git a/multisig/interaction/config/multitransfer-snippets.sh b/multisig/interaction/config/multitransfer-snippets.sh index 38304735..72a5a8cc 100644 --- a/multisig/interaction/config/multitransfer-snippets.sh +++ b/multisig/interaction/config/multitransfer-snippets.sh @@ -1,9 +1,8 @@ deployMultiTransfer() { - CHECK_VARIABLES MULTI_TRANSFER_WASM BRIDGED_TOKENS_WRAPPER + CHECK_VARIABLES MULTI_TRANSFER_WASM mxpy --verbose contract deploy --bytecode=${MULTI_TRANSFER_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=100000000 \ - --arguments ${BRIDGED_TOKENS_WRAPPER} --metadata-payable \ + --gas-limit=100000000 --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']") @@ -11,22 +10,23 @@ deployMultiTransfer() { echo "" echo "Multi transfer contract address: ${ADDRESS}" + update-config MULTI_TRANSFER ${ADDRESS} } -setLocalRolesMultiTransferEsdt() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS CHAIN_SPECIFIC_TOKEN MULTI_TRANSFER +setBridgeProxyContractAddress() { + CHECK_VARIABLES MULTI_TRANSFER BRIDGE_PROXY - 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 \ + mxpy --verbose contract call ${MULTI_TRANSFER} --recall-nonce --pem=${ALICE} \ + --gas-limit=60000000 --function="setBridgeProxyContractAddress" \ + --arguments ${BRIDGE_PROXY} \ --send --proxy=${PROXY} --chain=${CHAIN_ID} } -unsetLocalRolesMultiTransferEsdt() { - CHECK_VARIABLES ESDT_SYSTEM_SC_ADDRESS CHAIN_SPECIFIC_TOKEN MULTI_TRANSFER +setWrappingContractAddress() { + CHECK_VARIABLES MULTI_TRANSFER BRIDGED_TOKENS_WRAPPER - 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 \ + mxpy --verbose contract call ${MULTI_TRANSFER} --recall-nonce --pem=${ALICE} \ + --gas-limit=60000000 --function="setWrappingContractAddress" \ + --arguments ${BRIDGED_TOKENS_WRAPPER} \ --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 index 636c5cbc..57e6ad6d 100644 --- a/multisig/interaction/config/safe-snippets.sh +++ b/multisig/interaction/config/safe-snippets.sh @@ -14,6 +14,7 @@ deploySafe() { echo "" echo "Safe contract address: ${ADDRESS}" + update-config SAFE ${ADDRESS} } setLocalRolesEsdtSafe() { @@ -21,7 +22,7 @@ setLocalRolesEsdtSafe() { 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 \ + --arguments str:${CHAIN_SPECIFIC_TOKEN} ${SAFE} str:ESDTRoleLocalBurn str:ESDTRoleLocalMint \ --send --proxy=${PROXY} --chain=${CHAIN_ID} } @@ -30,6 +31,6 @@ unsetLocalRolesEsdtSafe() { 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 \ + --arguments str:${CHAIN_SPECIFIC_TOKEN} ${SAFE} str:ESDTRoleLocalBurn str:ESDTRoleLocalMint \ --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 index 5eeb077f..a612104a 100644 --- a/multisig/interaction/config/upgrade-snippets.sh +++ b/multisig/interaction/config/upgrade-snippets.sh @@ -2,7 +2,7 @@ deploySafeForUpgrade() { getAggregatorAddressHex - local ESDT_SAFE_ETH_TX_GAS_LIMIT=20000 # gives us 200$ for elrond->eth + local ESDT_SAFE_ETH_TX_GAS_LIMIT=20000 # gives us 200$ for multiversx->eth mxpy --verbose contract deploy --project=${PROJECT_SAFE} --recall-nonce --pem=${ALICE} \ --gas-limit=150000000 \ @@ -39,15 +39,23 @@ upgrade() { } upgradeMultisig() { - getMultiTransferEsdtAddressHex - getEsdtSafeAddressHex - getMultiTransferEsdtAddressHex + 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 MULTISIG_WASM - 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 - + mxpy --verbose contract upgrade ${MULTISIG} --bytecode=${MULTISIG_WASM} --recall-nonce --pem=${ALICE} \ + --gas-limit=200000000 \ + --arguments ${SAFE} ${MULTI_TRANSFER} \ + ${MIN_STAKE} ${SLASH_AMOUNT} ${QUORUM} \ + --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}" } \ No newline at end of file diff --git a/multisig/interaction/config/wrapped-snippets.sh b/multisig/interaction/config/wrapped-snippets.sh index 4985d888..ca1d7919 100644 --- a/multisig/interaction/config/wrapped-snippets.sh +++ b/multisig/interaction/config/wrapped-snippets.sh @@ -9,7 +9,7 @@ deployBridgedTokensWrapper() { CHECK_VARIABLES BRIDGED_TOKENS_WRAPPER_WASM mxpy --verbose contract deploy --bytecode=${BRIDGED_TOKENS_WRAPPER_WASM} --recall-nonce --pem=${ALICE} \ - --gas-limit=30000000 \ + --gas-limit=40000000 \ --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']") diff --git a/multisig/interaction/script.sh b/multisig/interaction/script.sh index ed684a2a..2f74347e 100755 --- a/multisig/interaction/script.sh +++ b/multisig/interaction/script.sh @@ -45,6 +45,14 @@ case "$1" in confirmation whitelist-token ;; +'whitelist-native-token') + echo -e + echo "Check and update TOKENS SETTINGS section in configs.cfg" + source $SCRIPTPATH/config/configs.cfg + echo -e + confirmation whitelist-native-token + ;; + 'remove-whitelist-token') echo -e echo "PREREQUIREMENTS: BRIDGED_TOKENS_WRAPPER needs to have MINT+BURN role for the UNIVERSAL TOKEN" diff --git a/multisig/meta/Cargo.toml b/multisig/meta/Cargo.toml index ec3e8100..e64607f0 100644 --- a/multisig/meta/Cargo.toml +++ b/multisig/meta/Cargo.toml @@ -9,5 +9,5 @@ publish = false path = ".." [dependencies.multiversx-sc-meta] -version = "0.45.2" +version = "0.46.1" default-features = false diff --git a/multisig/mandos/change_token_config.scen.json b/multisig/scenarios/change_token_config.scen.json similarity index 97% rename from multisig/mandos/change_token_config.scen.json rename to multisig/scenarios/change_token_config.scen.json index 8a9d0c73..75610ded 100644 --- a/multisig/mandos/change_token_config.scen.json +++ b/multisig/scenarios/change_token_config.scen.json @@ -154,7 +154,7 @@ "function": "addMapping", "arguments": [ "0x0102030405060708091011121314151617181999", - "str:EGLD-123456" + "str:WEGLD-123456" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -177,7 +177,7 @@ "function": "addMapping", "arguments": [ "0x0000030405060708091011121314151617181999", - "str:EGLD-123456" + "str:WEGLD-123456" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -202,7 +202,7 @@ }, "expect": { "out": [ - "str:EGLD-123456" + "str:WEGLD-123456" ] } }, @@ -213,7 +213,7 @@ "to": "sc:multisig", "function": "getErc20AddressForTokenId", "arguments": [ - "str:EGLD-123456" + "str:WEGLD-123456" ] }, "expect": { @@ -232,7 +232,7 @@ "function": "clearMapping", "arguments": [ "0x0102030405060708091011121314151617181920", - "str:EGLD-123456" + "str:WEGLD-123456" ], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/multisig/mandos/create_elrond_to_ethereum_tx_batch.scen.json b/multisig/scenarios/create_multiversx_to_ethereum_tx_batch.scen.json similarity index 77% rename from multisig/mandos/create_elrond_to_ethereum_tx_batch.scen.json rename to multisig/scenarios/create_multiversx_to_ethereum_tx_batch.scen.json index 1cd5744f..405d8d55 100644 --- a/multisig/mandos/create_elrond_to_ethereum_tx_batch.scen.json +++ b/multisig/scenarios/create_multiversx_to_ethereum_tx_batch.scen.json @@ -11,10 +11,13 @@ "tx": { "from": "address:user", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:EGLD-123456", - "value": "1,500,400" - }, + "value": "0", + "esdtValue": [ + { + "tokenIdentifier": "str:WEGLD-123456", + "value": "85,000,000,000" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -37,8 +40,8 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": "499,600", - "str:ETH-123456": "1,000,000" + "str:WEGLD-123456": "15,000,000,000", + "str:ETH-123456": "200,000,000,000" }, "storage": {} }, @@ -46,15 +49,17 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "1,500,400", + "str:WEGLD-123456": { + "balance": "85,000,000,000", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } @@ -65,13 +70,13 @@ "2-nonce": "u64:1", "3-from": "u32:32|address:user", "4-to": "u32:20|0x0102030405060708091011121314151617181920", - "5-token_identifier": "nested:str:EGLD-123456", - "6-amount": "biguint:400", + "5-token_identifier": "nested:str:WEGLD-123456", + "6-amount": "biguint:10,000,000,000", "7-is_refund_tx": "u8:0" }, "str:firstBatchId": "1", "str:lastBatchId": "1", - "str:accumulatedTransactionFees|nested:str:EGLD-123456": "1,500,000", + "str:accumulatedTransactionFees|nested:str:WEGLD-123456": "75,000,000,000", "+": "" }, "code": "*" @@ -85,10 +90,12 @@ "tx": { "from": "address:user", "to": "sc:esdt_safe", - "esdt": { - "tokenIdentifier": "str:ETH-123456", - "value": "500,000" - }, + "esdtValue": [ + { + "tokenIdentifier": "str:ETH-123456", + "value": "95,000,000,000" + } + ], "function": "createTransaction", "arguments": [ "0x0102030405060708091011121314151617181920" @@ -111,8 +118,8 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": "499,600", - "str:ETH-123456": "500,000" + "str:WEGLD-123456": "15,000,000,000", + "str:ETH-123456": "105,000,000,000" }, "storage": {} }, @@ -120,15 +127,17 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "1,500,400", + "str:WEGLD-123456": { + "balance": "85,000,000,000", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { - "balance": "500,000", + "balance": "95,000,000,000", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } @@ -139,8 +148,8 @@ "2-nonce": "u64:1", "3-from": "u32:32|address:user", "4-to": "u32:20|0x0102030405060708091011121314151617181920", - "5-token_identifier": "nested:str:EGLD-123456", - "6-amount": "biguint:400", + "5-token_identifier": "nested:str:WEGLD-123456", + "6-amount": "biguint:10,000,000,000", "7-is_refund_tx": "u8:0" }, "str:pendingBatches|u64:1|str:.item|u32:2": { @@ -149,13 +158,13 @@ "3-from": "u32:32|address:user", "4-to": "u32:20|0x0102030405060708091011121314151617181920", "5-token_identifier": "nested:str:ETH-123456", - "6-amount": "biguint:350,000", + "6-amount": "biguint:20,000,000,000", "7-is_refund_tx": "u8:0" }, "str:firstBatchId": "1", "str:lastBatchId": "1", - "str:accumulatedTransactionFees|nested:str:EGLD-123456": "1,500,000", - "str:accumulatedTransactionFees|nested:str:ETH-123456": "150,000", + "str:accumulatedTransactionFees|nested:str:WEGLD-123456": "75,000,000,000", + "str:accumulatedTransactionFees|nested:str:ETH-123456": "75,000,000,000", "+": "" }, "code": "*" @@ -184,16 +193,16 @@ "1", "address:user", "0x0102030405060708091011121314151617181920", - "str:EGLD-123456", - "400", + "str:WEGLD-123456", + "10,000,000,000", "0", "2", "address:user", "0x0102030405060708091011121314151617181920", "str:ETH-123456", - "350,000" + "20,000,000,000" ] } } ] -} +} \ No newline at end of file diff --git a/multisig/mandos/ethereum_to_elrond_tx_batch_ok.scen.json b/multisig/scenarios/ethereum_to_multiversx_tx_batch_ok.scen.json similarity index 77% rename from multisig/mandos/ethereum_to_elrond_tx_batch_ok.scen.json rename to multisig/scenarios/ethereum_to_multiversx_tx_batch_ok.scen.json index 86fe3a03..81310661 100644 --- a/multisig/mandos/ethereum_to_elrond_tx_batch_ok.scen.json +++ b/multisig/scenarios/ethereum_to_multiversx_tx_batch_ok.scen.json @@ -1,5 +1,5 @@ { - "name": "create ethereum to elrond tx batch", + "name": "create ethereum to MultiversX tx batch", "steps": [ { "step": "externalSteps", @@ -15,8 +15,8 @@ "function": "proposeMultiTransferEsdtBatch", "arguments": [ "1", - "0x0102030405060708091011121314151617181920", "address:user", "str:EGLD-123456", "500,000", "1", - "0x0102030405060708091011121314151617181920", "address:user", "str:ETH-123456", "500,000", "2" + "0x0102030405060708091011121314151617181920", "address:user", "str:WEGLD-123456", "76,000,000,000", "1", "str:data", "u64:20000000", "0", + "0x0102030405060708091011121314151617181920", "address:user", "str:ETH-123456", "76,000,000,000", "2", "str:data", "u64:20000000", "0" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -46,16 +46,22 @@ { "1-from": "0x0102030405060708091011121314151617181920", "2-to": "address:user", - "3-token_id": "nested:str:EGLD-123456", - "4-amount": "biguint:500,000", - "5-tx_nonce": "u64:1" + "3-token_id": "nested:str:WEGLD-123456", + "4-amount": "biguint:76,000,000,000", + "5-tx_nonce": "u64:1", + "6-data": "nested:str:data", + "7-gas_limit": "u64:20000000", + "8-args": "nested:0" }, { "1-from": "0x0102030405060708091011121314151617181920", "2-to": "address:user", "3-token_id": "nested:str:ETH-123456", - "4-amount": "biguint:500,000", - "5-tx_nonce": "u64:2" + "4-amount": "biguint:76,000,000,000", + "5-tx_nonce": "u64:2", + "6-data": "nested:str:data", + "7-gas_limit": "u64:20000000", + "8-args": "nested:0" } ] }, @@ -117,8 +123,8 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": "2,500,000", - "str:ETH-123456": "1,500,000" + "str:WEGLD-123456": "176,000,000,000", + "str:ETH-123456": "276,000,000,000" }, "storage": {} }, diff --git a/multisig/mandos/ethereum_to_elrond_tx_batch_rejected.scen.json b/multisig/scenarios/ethereum_to_multiversx_tx_batch_rejected.scen.json similarity index 80% rename from multisig/mandos/ethereum_to_elrond_tx_batch_rejected.scen.json rename to multisig/scenarios/ethereum_to_multiversx_tx_batch_rejected.scen.json index f3d8f739..1c1076c6 100644 --- a/multisig/mandos/ethereum_to_elrond_tx_batch_rejected.scen.json +++ b/multisig/scenarios/ethereum_to_multiversx_tx_batch_rejected.scen.json @@ -1,5 +1,5 @@ { - "name": "create ethereum to elrond tx batch - rejected", + "name": "create ethereum to MultiversX tx batch - rejected", "steps": [ { "step": "externalSteps", @@ -17,14 +17,20 @@ "2", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", - "str:EGLD-123456", - "2,000,000", + "str:WEGLD-123456", + "76,000,000,000", + "str:data", + "u64:2,000,000", "u64:1", + "0", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", "str:ETH-123456", - "2,000,000", - "u64:2" + "76,000,000,000", + "u64:2", + "str:data", + "u64:2,000,000", + "0" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -49,14 +55,20 @@ "1", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", - "str:EGLD-123456", - "2,000,000", + "str:WEGLD-123456", + "76,000,000,000", "u64:2", + "str:data", + "u64:2,000,000", + "0", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", "str:ETH-123456", - "2,000,000", - "u64:3" + "76,000,000,000", + "u64:3", + "str:data", + "u64:2,000,000", + "0" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -81,14 +93,20 @@ "1", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", - "str:EGLD-123456", - "2,000,000", + "str:WEGLD-123456", + "76,000,000,000", "u64:1", + "str:data", + "u64:2,000,000", + "0", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", "str:ETH-123456", - "2,000,000", - "u64:2" + "76,000,000,000", + "u64:2", + "str:data", + "u64:2,000,000", + "0" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -118,16 +136,22 @@ { "1-from": "0x0102030405060708091011121314151617181920", "2-to": "sc:egld_esdt_swap", - "3-token_id": "nested:str:EGLD-123456", - "4-amount": "biguint:2,000,000", - "5-tx_id": "u64:1" + "3-token_id": "nested:str:WEGLD-123456", + "4-amount": "biguint:76,000,000,000", + "5-tx_id": "u64:1", + "6-data": "nested:str:data", + "7-gas_limit": "u64:2,000,000", + "8-args": "nested:0" }, { "1-from": "0x0102030405060708091011121314151617181920", "2-to": "sc:egld_esdt_swap", "3-token_id": "nested:str:ETH-123456", - "4-amount": "biguint:2,000,000", - "5-tx_id": "u64:2" + "4-amount": "biguint:76,000,000,000", + "5-tx_id": "u64:2", + "6-data": "nested:str:data", + "7-gas_limit": "u64:2,000,000", + "8-args": "nested:0" } ] }, @@ -198,14 +222,14 @@ "1", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", - "str:EGLD-123456", - "2,000,000", + "str:WEGLD-123456", + "76,000,000,000", "0", "2", "0x0102030405060708091011121314151617181920", "sc:egld_esdt_swap", "str:ETH-123456", - "2,000,000" + "76,000,000,000" ] } }, @@ -248,15 +272,17 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { + "str:WEGLD-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } @@ -267,8 +293,8 @@ "2-nonce": "u64:1", "3-from": "u32:32|sc:egld_esdt_swap", "4-to": "u32:20|0x0102030405060708091011121314151617181920", - "5-token_identifier": "nested:str:EGLD-123456", - "6-amount": "biguint:500,000", + "5-token_identifier": "nested:str:WEGLD-123456", + "6-amount": "biguint:1,000,000,000", "7-is_refund_tx": "u8:1" }, "str:pendingBatches|u64:1|str:.item|u32:2": { @@ -277,12 +303,12 @@ "3-from": "u32:32|sc:egld_esdt_swap", "4-to": "u32:20|0x0102030405060708091011121314151617181920", "5-token_identifier": "nested:str:ETH-123456", - "6-amount": "biguint:1,850,000", + "6-amount": "biguint:1,000,000,000", "7-is_refund_tx": "u8:1" }, "str:firstBatchId": "1", "str:lastBatchId": "1", - "str:accumulatedTransactionFees|nested:str:EGLD-123456": "0", + "str:accumulatedTransactionFees|nested:str:WEGLD-123456": "0", "str:accumulatedTransactionFees|nested:str:ETH-123456": "0", "+": "" }, diff --git a/multisig/mandos/execute_elrond_to_ethereum_tx_batch.scen.json b/multisig/scenarios/execute_multiversx_to_ethereum_tx_batch.scen.json similarity index 89% rename from multisig/mandos/execute_elrond_to_ethereum_tx_batch.scen.json rename to multisig/scenarios/execute_multiversx_to_ethereum_tx_batch.scen.json index 77368000..6a7acfa9 100644 --- a/multisig/mandos/execute_elrond_to_ethereum_tx_batch.scen.json +++ b/multisig/scenarios/execute_multiversx_to_ethereum_tx_batch.scen.json @@ -3,7 +3,7 @@ "steps": [ { "step": "externalSteps", - "path": "create_elrond_to_ethereum_tx_batch.scen.json" + "path": "create_multiversx_to_ethereum_tx_batch.scen.json" }, { "step": "scCall", @@ -103,7 +103,7 @@ "value": "0", "function": "claimRefund", "arguments": [ - "str:EGLD-123456" + "str:WEGLD-123456" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -144,15 +144,17 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "1,500,000", + "str:WEGLD-123456": { + "balance": "75,000,000,000", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { - "balance": "150,000", + "balance": "75,000,000,000", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } @@ -162,8 +164,8 @@ "str:transactionsByNonce|address:user|str:.item|u32:1": "", "str:transactionStatus|address:user|u32:2": "", "str:transactionsByNonce|address:user|str:.item|u32:2": "", - "str:accumulatedTransactionFees|nested:str:EGLD-123456": "1,500,000", - "str:accumulatedTransactionFees|nested:str:ETH-123456": "150,000", + "str:accumulatedTransactionFees|nested:str:WEGLD-123456": "75,000,000,000", + "str:accumulatedTransactionFees|nested:str:ETH-123456": "75,000,000,000", "+": "" }, "code": "*" @@ -202,11 +204,11 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "600,000" + "str:WEGLD-123456": { + "balance": "30,000,000,000" }, "str:ETH-123456": { - "balance": "60,000" + "balance": "30,000,000,000" } }, "storage": {} @@ -215,11 +217,11 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "900,000" + "str:WEGLD-123456": { + "balance": "45,000,000,000" }, "str:ETH-123456": { - "balance": "90,000" + "balance": "45,000,000,000" } }, "storage": {} @@ -228,21 +230,23 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { + "str:WEGLD-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } }, "storage": { - "str:accumulatedTransactionFees|nested:str:EGLD-123456": "0", + "str:accumulatedTransactionFees|nested:str:WEGLD-123456": "0", "str:accumulatedTransactionFees|nested:str:ETH-123456": "0", "+": "" }, diff --git a/multisig/mandos/get_empty_batch.scen.json b/multisig/scenarios/get_empty_batch.scen.json similarity index 100% rename from multisig/mandos/get_empty_batch.scen.json rename to multisig/scenarios/get_empty_batch.scen.json diff --git a/multisig/mandos/reject_elrond_to_ethereum_tx_batch.scen.json b/multisig/scenarios/reject_multiversx_to_ethereum_tx_batch.scen.json similarity index 87% rename from multisig/mandos/reject_elrond_to_ethereum_tx_batch.scen.json rename to multisig/scenarios/reject_multiversx_to_ethereum_tx_batch.scen.json index 1150e544..bea7cd56 100644 --- a/multisig/mandos/reject_elrond_to_ethereum_tx_batch.scen.json +++ b/multisig/scenarios/reject_multiversx_to_ethereum_tx_batch.scen.json @@ -3,7 +3,7 @@ "steps": [ { "step": "externalSteps", - "path": "create_elrond_to_ethereum_tx_batch.scen.json" + "path": "create_multiversx_to_ethereum_tx_batch.scen.json" }, { "step": "scCall", @@ -106,10 +106,10 @@ }, "expect": { "out": [ - "str:EGLD-123456", - "400", + "str:WEGLD-123456", + "10,000,000,000", "str:ETH-123456", - "350,000" + "20,000,000,000" ] } }, @@ -122,7 +122,7 @@ "value": "0", "function": "claimRefund", "arguments": [ - "str:EGLD-123456" + "str:WEGLD-123456" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -165,8 +165,8 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": "500,000", - "str:ETH-123456": "850,000" + "str:WEGLD-123456": "25,000,000,000", + "str:ETH-123456": "125,000,000,000" }, "storage": {} }, @@ -174,15 +174,17 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "1,500,000", + "str:WEGLD-123456": { + "balance": "75,000,000,000", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { - "balance": "150,000", + "balance": "75,000,000,000", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } @@ -192,8 +194,8 @@ "str:transactionsByNonce|address:user|str:.item|u32:1": "", "str:transactionStatus|address:user|u32:2": "", "str:transactionsByNonce|address:user|str:.item|u32:2": "", - "str:accumulatedTransactionFees|nested:str:EGLD-123456": "1,500,000", - "str:accumulatedTransactionFees|nested:str:ETH-123456": "150,000", + "str:accumulatedTransactionFees|nested:str:WEGLD-123456": "75,000,000,000", + "str:accumulatedTransactionFees|nested:str:ETH-123456": "75,000,000,000", "+": "" }, "code": "*" @@ -232,11 +234,11 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "600,000" + "str:WEGLD-123456": { + "balance": "30,000,000,000" }, "str:ETH-123456": { - "balance": "60,000" + "balance": "30,000,000,000" } }, "storage": {} @@ -245,11 +247,11 @@ "nonce": "*", "balance": "0", "esdt": { - "str:EGLD-123456": { - "balance": "900,000" + "str:WEGLD-123456": { + "balance": "45,000,000,000" }, "str:ETH-123456": { - "balance": "90,000" + "balance": "45,000,000,000" } }, "storage": {} @@ -258,21 +260,23 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { + "str:WEGLD-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } }, "storage": { - "str:accumulatedTransactionFees|nested:str:EGLD-123456": "0", + "str:accumulatedTransactionFees|nested:str:WEGLD-123456": "0", "str:accumulatedTransactionFees|nested:str:ETH-123456": "0", "+": "" }, diff --git a/multisig/mandos/setup.scen.json b/multisig/scenarios/setup.scen.json similarity index 72% rename from multisig/mandos/setup.scen.json rename to multisig/scenarios/setup.scen.json index 9739684e..2be0fe38 100644 --- a/multisig/mandos/setup.scen.json +++ b/multisig/scenarios/setup.scen.json @@ -3,7 +3,7 @@ "steps": [ { "step": "externalSteps", - "path": "../../price-aggregator/mandos/oracle_gwei_in_eth_and_egld_submit.scen.json" + "path": "../../price-aggregator/scenarios/oracle_gwei_in_eth_and_egld_submit.scen.json" }, { "step": "setState", @@ -13,7 +13,7 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { + "str:WEGLD-123456": { "balance": "0", "roles": [ "ESDTRoleLocalMint" @@ -27,6 +27,8 @@ } }, "storage": { + "str:esdtSafeContractAddress": "sc:esdt_safe", + "str:maxTxBatchSize": "10", "str:maxTxBatchBlockDuration": "3,600", @@ -40,20 +42,23 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": { + "str:WEGLD-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] }, "str:ETH-123456": { "balance": "0", "roles": [ + "ESDTRoleLocalMint", "ESDTRoleLocalBurn" ] } }, "storage": { + "str:multiTransferContractAddress": "sc:multi_transfer", "str:feeEstimatorContractAddress": "sc:price_aggregator", "str:maxTxBatchSize": "10", "str:maxTxBatchBlockDuration": "100", @@ -63,11 +68,11 @@ "str:lastBatchId": "1", "str:tokenTicker|nested:str:GWEI": "str:GWEI", - "str:tokenTicker|nested:str:EGLD-123456": "str:EGLD", + "str:tokenTicker|nested:str:WEGLD-123456": "str:WEGLD", "str:tokenTicker|nested:str:ETH-123456": "str:ETH", - "str:tokenWhitelist.index|nested:str:EGLD-123456": "1", - "str:tokenWhitelist.item|u32:1": "str:EGLD-123456", + "str:tokenWhitelist.index|nested:str:WEGLD-123456": "1", + "str:tokenWhitelist.item|u32:1": "str:WEGLD-123456", "str:tokenWhitelist.index|nested:str:ETH-123456": "2", "str:tokenWhitelist.item|u32:2": "str:ETH-123456", "str:tokenWhitelist.len": "2" @@ -99,10 +104,15 @@ "nonce": "0", "balance": "0", "esdt": { - "str:EGLD-123456": "2,000,000", - "str:ETH-123456": "1,000,000" + "str:WEGLD-123456": "100,000,000,000", + "str:ETH-123456": "200,000,000,000" }, "storage": {} + }, + "sc:egld_esdt_swap": { + "nonce": "0", + "balance": "0", + "code": "sc:egld_esdt_swap" } }, "newAddresses": [ @@ -277,7 +287,7 @@ }, "expect": { "out": [ - "str:EGLD-123456", + "str:WEGLD-123456", "str:ETH-123456" ] } @@ -300,6 +310,96 @@ "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "sc:multisig", + "to": "sc:esdt_safe", + "value": "0", + "function": "addTokenToWhitelist", + "arguments": [ + "str:WEGLD-123456", + "str:WEGLD", + "true", + "500,000" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "add-token-1", + "tx": { + "from": "sc:multisig", + "to": "sc:esdt_safe", + "value": "0", + "function": "addTokenToWhitelist", + "arguments": [ + "str:ETH-123456", + "str:ETH", + "true", + "500,000" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-accumulated-burned-tokens", + "tx": { + "from": "sc:multisig", + "to": "sc:esdt_safe", + "function": "setAccumulatedBurnedTokens", + "arguments": [ + "str:WEGLD-123456", + "500,000,000,000" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "set-accumulated-burned-tokens", + "tx": { + "from": "sc:multisig", + "to": "sc:esdt_safe", + "function": "setAccumulatedBurnedTokens", + "arguments": [ + "str:ETH-123456", + "500,000,000,000" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } } ] } diff --git a/multisig/mandos/unstake.scen.json b/multisig/scenarios/unstake.scen.json similarity index 100% rename from multisig/mandos/unstake.scen.json rename to multisig/scenarios/unstake.scen.json diff --git a/multisig/src/setup.rs b/multisig/src/setup.rs index 624b1c98..85abd174 100644 --- a/multisig/src/setup.rs +++ b/multisig/src/setup.rs @@ -171,7 +171,7 @@ pub trait SetupModule: /// where price_per_gas_unit is queried from the aggregator (fee estimator SC) #[only_owner] #[endpoint(changeElrondToEthGasLimit)] - fn change_elrond_to_eth_gas_limit(&self, new_gas_limit: BigUint) { + fn change_multiversx_to_eth_gas_limit(&self, new_gas_limit: BigUint) { let _: IgnoreValue = self .get_esdt_safe_proxy_instance() .set_eth_tx_gas_limit(new_gas_limit) @@ -205,11 +205,35 @@ pub trait SetupModule: &self, token_id: TokenIdentifier, ticker: ManagedBuffer, + mint_burn_allowed: bool, opt_default_price_per_gas_unit: OptionalValue, ) { let _: IgnoreValue = self .get_esdt_safe_proxy_instance() - .add_token_to_whitelist(token_id, ticker, opt_default_price_per_gas_unit) + .add_token_to_whitelist( + token_id, + ticker, + mint_burn_allowed, + opt_default_price_per_gas_unit, + ) + .execute_on_dest_context(); + } + + #[only_owner] + #[endpoint(setMultiTransferOnEsdtSafe)] + fn set_multi_transfer_on_esdt_safe(&self) { + let _: IgnoreValue = self + .get_esdt_safe_proxy_instance() + .set_multi_transfer_contract_address(self.multi_transfer_esdt_address().get()) + .execute_on_dest_context(); + } + + #[only_owner] + #[endpoint(setEsdtSafeOnMultiTransfer)] + fn set_esdt_safe_on_multi_transfer(&self) { + let _: IgnoreValue = self + .get_multi_transfer_esdt_proxy_instance() + .set_esdt_safe_contract_address(self.esdt_safe_address().get()) .execute_on_dest_context(); } diff --git a/multisig/src/util.rs b/multisig/src/util.rs index 96fc007b..df489c64 100644 --- a/multisig/src/util.rs +++ b/multisig/src/util.rs @@ -49,7 +49,7 @@ pub trait UtilModule: crate::storage::StorageModule { ) -> ManagedVec> { let mut transfers_as_eth_tx = ManagedVec::new(); for transfer in transfers { - let (from, to, token_id, amount, tx_nonce) = transfer.into_tuple(); + let (from, to, token_id, amount, tx_nonce, data, gas_limit, args) = transfer.into_tuple(); transfers_as_eth_tx.push(EthTransaction { from, @@ -57,6 +57,9 @@ pub trait UtilModule: crate::storage::StorageModule { token_id, amount, tx_nonce, + data, + gas_limit, + args }); } diff --git a/multisig/tests/multisig_scenario_rs_test.rs b/multisig/tests/multisig_scenario_rs_test.rs new file mode 100644 index 00000000..a615f95e --- /dev/null +++ b/multisig/tests/multisig_scenario_rs_test.rs @@ -0,0 +1,58 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + blockchain.set_current_dir_from_workspace("multisig/"); + + blockchain.register_contract("file:output/multisig.wasm", multisig::ContractBuilder); + blockchain.register_contract("file:../multi-transfer-esdt/output/multi-transfer-esdt.wasm", multi_transfer_esdt::ContractBuilder); + blockchain.register_contract("file:../esdt-safe/output/esdt-safe.wasm", esdt_safe::ContractBuilder); + blockchain.register_contract("file:../price-aggregator/multiversx-price-aggregator-sc.wasm", multiversx_price_aggregator_sc::ContractBuilder); + + blockchain +} + +#[test] +fn change_token_config_rs() { + world().run("scenarios/change_token_config.scen.json"); +} + +#[test] +fn create_multiversx_to_ethereum_tx_batch_rs() { + world().run("scenarios/create_multiversx_to_ethereum_tx_batch.scen.json"); +} + +#[test] +fn ethereum_to_multiversx_tx_batch_ok_rs() { + world().run("scenarios/ethereum_to_multiversx_tx_batch_ok.scen.json"); +} + +#[test] +fn ethereum_to_multiversx_tx_batch_rejected_rs() { + world().run("scenarios/ethereum_to_multiversx_tx_batch_rejected.scen.json"); +} + +#[test] +fn execute_multiversx_to_ethereum_tx_batch_rs() { + world().run("scenarios/execute_multiversx_to_ethereum_tx_batch.scen.json"); +} + +#[test] +fn get_empty_batch_rs() { + world().run("scenarios/get_empty_batch.scen.json"); +} + +#[test] +fn reject_multiversx_to_ethereum_tx_batch_rs() { + world().run("scenarios/reject_multiversx_to_ethereum_tx_batch.scen.json"); +} + +#[test] +fn setup_rs() { + world().run("scenarios/setup.scen.json"); +} + +#[test] +fn unstake_rs() { + world().run("scenarios/unstake.scen.json"); +} diff --git a/multisig/tests/scenario_go_test.rs b/multisig/tests/scenario_go_test.rs index 9605e9d4..aed76ed9 100644 --- a/multisig/tests/scenario_go_test.rs +++ b/multisig/tests/scenario_go_test.rs @@ -1,46 +1,49 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} #[test] -fn create_elrond_to_ethereum_tx_batch_go() { - multiversx_sc_scenario::run_go("mandos/create_elrond_to_ethereum_tx_batch.scen.json"); +fn change_token_config_go() { + world().run("scenarios/change_token_config.scen.json"); } #[test] -fn ethereum_to_elrond_tx_batch_ok_go() { - multiversx_sc_scenario::run_go("mandos/ethereum_to_elrond_tx_batch_ok.scen.json"); +fn create_multiversx_to_ethereum_tx_batch_go() { + world().run("scenarios/create_multiversx_to_ethereum_tx_batch.scen.json"); } #[test] -fn ethereum_to_elrond_tx_batch_rejected_go() { - multiversx_sc_scenario::run_go("mandos/ethereum_to_elrond_tx_batch_rejected.scen.json"); +fn ethereum_to_multiversx_tx_batch_ok_go() { + world().run("scenarios/ethereum_to_multiversx_tx_batch_ok.scen.json"); } #[test] -fn execute_elrond_to_ethereum_tx_batch_go() { - multiversx_sc_scenario::run_go("mandos/execute_elrond_to_ethereum_tx_batch.scen.json"); +fn ethereum_to_multiversx_tx_batch_rejected_go() { + world().run("scenarios/ethereum_to_multiversx_tx_batch_rejected.scen.json"); } #[test] -fn get_empty_batch_go() { - multiversx_sc_scenario::run_go("mandos/get_empty_batch.scen.json"); +fn execute_multiversx_to_ethereum_tx_batch_go() { + world().run("scenarios/execute_multiversx_to_ethereum_tx_batch.scen.json"); } #[test] -fn reject_elrond_to_ethereum_tx_batch_go() { - multiversx_sc_scenario::run_go("mandos/reject_elrond_to_ethereum_tx_batch.scen.json"); +fn get_empty_batch_go() { + world().run("scenarios/get_empty_batch.scen.json"); } #[test] -fn setup_go() { - multiversx_sc_scenario::run_go("mandos/setup.scen.json"); +fn reject_multiversx_to_ethereum_tx_batch_go() { + world().run("scenarios/reject_multiversx_to_ethereum_tx_batch.scen.json"); } #[test] -fn unstake_go() { - multiversx_sc_scenario::run_go("mandos/unstake.scen.json"); +fn setup_go() { + world().run("scenarios/setup.scen.json"); } -/* #[test] -fn upgrade_child_sc_go() { - multiversx_sc_scenario::run_go("mandos/upgrade_child_sc.scen.json"); +fn unstake_go() { + world().run("scenarios/unstake.scen.json"); } -*/ diff --git a/multisig/wasm/Cargo.lock b/multisig/wasm/Cargo.lock index b114b035..e7801f46 100644 --- a/multisig/wasm/Cargo.lock +++ b/multisig/wasm/Cargo.lock @@ -3,23 +3,13 @@ version = 3 [[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +name = "adder" +version = "0.0.0" +source = "git+https://github.com/multiversx/mx-contracts-rs?rev=64e8926#64e892655f9c59b2aafe07800af61d0fa41c6ddc" dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", + "multiversx-sc", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" version = "0.7.4" @@ -34,9 +24,19 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "bridge-proxy" +version = "0.0.0" +dependencies = [ + "adder", + "eth-address", + "multiversx-sc", + "transaction", +] [[package]] name = "bridged-tokens-wrapper" @@ -47,6 +47,12 @@ dependencies = [ "transaction", ] +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "cfg-if" version = "1.0.0" @@ -66,6 +72,7 @@ dependencies = [ "eth-address", "fee-estimator-module", "max-bridged-amount-module", + "multiversx-price-aggregator-sc", "multiversx-sc", "multiversx-sc-modules", "token-module", @@ -88,13 +95,16 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.14.3" +name = "getrandom" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ - "ahash", - "allocator-api2", + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", ] [[package]] @@ -109,6 +119,27 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "max-bridged-amount-module" version = "0.0.0" @@ -120,9 +151,14 @@ dependencies = [ name = "multi-transfer-esdt" version = "0.0.0" dependencies = [ + "bridge-proxy", "bridged-tokens-wrapper", + "esdt-safe", + "eth-address", "max-bridged-amount-module", "multiversx-sc", + "multiversx-sc-modules", + "token-module", "transaction", "tx-batch-module", ] @@ -136,6 +172,7 @@ dependencies = [ "fee-estimator-module", "max-bridged-amount-module", "multi-transfer-esdt", + "multiversx-price-aggregator-sc", "multiversx-sc", "multiversx-sc-modules", "token-module", @@ -151,14 +188,26 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] +[[package]] +name = "multiversx-price-aggregator-sc" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8de03c6796bd16c39cafafd13da688d9f64d30965866d1c0d0badd2071235f9" +dependencies = [ + "arrayvec", + "getrandom", + "multiversx-sc", + "multiversx-sc-modules", + "rand", +] + [[package]] name = "multiversx-sc" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2bdb196b3ff2b9f8c744ec2e026c22c8e02bc91e5c6ed09951415c47fef6b8" +checksum = "6c94b173dc5ff0e157f767275fe6b7a1b4d2ad343bef7b66cd22a6353e016b93" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", @@ -189,9 +238,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e60b5dce707f61376f74d713218f75326121d9f6a5f09a3a63de7aea2a92be9" +checksum = "3b78945957036c281ad6ee21bb5120dcefa2017688adf43ec94e3e7c982efb09" dependencies = [ "hex", "proc-macro2", @@ -202,18 +251,18 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5833f8bc88104357d38a8952d2a16c3e66080e2e512c0e7001c0c003006c475" +checksum = "c63ffaba95e630ff75981e2f5f50da64f523219b52f484234c66f3adc248885f" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.45.2" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4299660d5413d9f120bfddda8105b1f9d28f0345a72f53e5dc90732c4983e45" +checksum = "9579f40c00da56a5a68e010ff851fa48ac7b9c6a16ad4314795cb32d889d9e78" dependencies = [ "multiversx-sc", ] @@ -229,33 +278,39 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -270,17 +325,47 @@ dependencies = [ "nibble_vec", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -313,32 +398,66 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] [[package]] -name = "version_check" -version = "0.9.4" +name = "wasm-bindgen-backend" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] [[package]] -name = "zerocopy" -version = "0.7.31" +name = "wasm-bindgen-macro" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ - "zerocopy-derive", + "quote", + "wasm-bindgen-macro-support", ] [[package]] -name = "zerocopy-derive" -version = "0.7.31" +name = "wasm-bindgen-macro-support" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" diff --git a/multisig/wasm/Cargo.toml b/multisig/wasm/Cargo.toml index b6d0ab00..50d26db2 100644 --- a/multisig/wasm/Cargo.toml +++ b/multisig/wasm/Cargo.toml @@ -25,7 +25,7 @@ overflow-checks = false path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.45.2" +version = "0.46.1" [workspace] members = ["."] diff --git a/multisig/wasm/src/lib.rs b/multisig/wasm/src/lib.rs index 9d0cd26b..f5203310 100644 --- a/multisig/wasm/src/lib.rs +++ b/multisig/wasm/src/lib.rs @@ -5,14 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 62 +// Endpoints: 64 // Async Callback (empty): 1 -// Total number of exported functions: 64 +// Total number of exported functions: 66 #![no_std] - -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. +#![allow(internal_features)] #![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); @@ -41,10 +39,12 @@ multiversx_sc_wasm_adapter::endpoints! { pauseEsdtSafe => pause_esdt_safe unpauseEsdtSafe => unpause_esdt_safe changeFeeEstimatorContractAddress => change_fee_estimator_contract_address - changeElrondToEthGasLimit => change_elrond_to_eth_gas_limit + changeElrondToEthGasLimit => change_multiversx_to_eth_gas_limit changeDefaultPricePerGasUnit => change_default_price_per_gas_unit changeTokenTicker => change_token_ticker esdtSafeAddTokenToWhitelist => esdt_safe_add_token_to_whitelist + setMultiTransferOnEsdtSafe => set_multi_transfer_on_esdt_safe + setEsdtSafeOnMultiTransfer => set_esdt_safe_on_multi_transfer esdtSafeRemoveTokenFromWhitelist => esdt_safe_remove_token_from_whitelist esdtSafeSetMaxTxBatchSize => esdt_safe_set_max_tx_batch_size esdtSafeSetMaxTxBatchBlockDuration => esdt_safe_set_max_tx_batch_block_duration diff --git a/price-aggregator/mandos/deploy.scen.json b/price-aggregator/mandos/deploy.scen.json deleted file mode 100644 index c7474748..00000000 --- a/price-aggregator/mandos/deploy.scen.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "name": "deploy", - "steps": [ - { - "step": "setState", - "accounts": { - "address:aggregator-owner": { - "nonce": "0", - "balance": "0", - "storage": {} - }, - "address:oracle": { - "nonce": "0", - "balance": "0", - "storage": {} - } - }, - "newAddresses": [ - { - "creatorAddress": "address:aggregator-owner", - "creatorNonce": "0", - "newAddress": "sc:price_aggregator" - } - ] - }, - { - "step": "scDeploy", - "txId": "deploy", - "tx": { - "from": "address:aggregator-owner", - "contractCode": "file:../price-aggregator.wasm", - "value": "0", - "arguments": [ - "1", - "0", - "address:oracle" - ], - "gasLimit": "20,000,000", - "gasPrice": "0" - }, - "expect": { - "status": "0", - "message": "", - "gas": "*", - "refund": "*" - } - }, - { - "step": "scCall", - "txId": "unpause", - "tx": { - "from": "address:aggregator-owner", - "to": "sc:price_aggregator", - "value": "0", - "function": "unpause", - "arguments": [], - "gasLimit": "100,000,000", - "gasPrice": "0" - }, - "expect": { - "status": "0", - "message": "", - "out": [], - "gas": "*", - "refund": "*" - } - }, - { - "step": "checkState", - "accounts": { - "address:aggregator-owner": { - "nonce": "2", - "balance": "0", - "storage": {} - }, - "sc:price_aggregator": { - "nonce": "0", - "balance": "0", - "storage": { - "str:submission_count": "1", - "str:decimals": "0", - "str:oracle_status.mapped|address:oracle": { - "0-total_submissions": "u64:0", - "1-accepted_submissions": "u64:0" - }, - "+": "" - }, - "code": "file:../price-aggregator.wasm" - }, - "+": {} - } - } - ] -} diff --git a/price-aggregator/mandos/oracle_submit.scen.json b/price-aggregator/mandos/oracle_submit.scen.json deleted file mode 100644 index 02dd2172..00000000 --- a/price-aggregator/mandos/oracle_submit.scen.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "oracle submit", - "steps": [ - { - "step": "externalSteps", - "path": "deploy.scen.json" - }, - { - "step": "scCall", - "txId": "oracle-submit", - "tx": { - "from": "address:oracle", - "to": "sc:price_aggregator", - "value": "0", - "function": "submit", - "arguments": [ - "str:GWEI", - "str:BRIDGE", - "10" - ], - "gasLimit": "40,000,000", - "gasPrice": "0" - }, - "expect": { - "status": "0", - "message": "", - "gas": "*", - "refund": "*" - } - } - ] -} diff --git a/price-aggregator/multiversx-price-aggregator-sc.abi.json b/price-aggregator/multiversx-price-aggregator-sc.abi.json new file mode 100644 index 00000000..32b96429 --- /dev/null +++ b/price-aggregator/multiversx-price-aggregator-sc.abi.json @@ -0,0 +1,440 @@ +{ + "buildInfo": { + "rustc": { + "version": "1.71.0-nightly", + "commitHash": "a2b1646c597329d0a25efa3889b66650f65de1de", + "commitDate": "2023-05-25", + "channel": "Nightly", + "short": "rustc 1.71.0-nightly (a2b1646c5 2023-05-25)" + }, + "contractCrate": { + "name": "multiversx-price-aggregator-sc", + "version": "0.45.2", + "gitVersion": "v0.45.2-2-g3aa173014" + }, + "framework": { + "name": "multiversx-sc", + "version": "0.45.2" + } + }, + "name": "PriceAggregator", + "constructor": { + "inputs": [ + { + "name": "staking_token", + "type": "EgldOrEsdtTokenIdentifier" + }, + { + "name": "staking_amount", + "type": "BigUint" + }, + { + "name": "slash_amount", + "type": "BigUint" + }, + { + "name": "slash_quorum", + "type": "u32" + }, + { + "name": "submission_count", + "type": "u32" + }, + { + "name": "oracles", + "type": "variadic
", + "multi_arg": true + } + ], + "outputs": [] + }, + "endpoints": [ + { + "name": "changeAmounts", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "staking_amount", + "type": "BigUint" + }, + { + "name": "slash_amount", + "type": "BigUint" + } + ], + "outputs": [] + }, + { + "name": "addOracles", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "oracles", + "type": "variadic
", + "multi_arg": true + } + ], + "outputs": [] + }, + { + "docs": [ + "Also receives submission count,", + "so the owner does not have to update it manually with setSubmissionCount before this call" + ], + "name": "removeOracles", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "submission_count", + "type": "u32" + }, + { + "name": "oracles", + "type": "variadic
", + "multi_arg": true + } + ], + "outputs": [] + }, + { + "name": "submit", + "mutability": "mutable", + "inputs": [ + { + "name": "from", + "type": "bytes" + }, + { + "name": "to", + "type": "bytes" + }, + { + "name": "submission_timestamp", + "type": "u64" + }, + { + "name": "price", + "type": "BigUint" + }, + { + "name": "decimals", + "type": "u8" + } + ], + "outputs": [] + }, + { + "name": "submitBatch", + "mutability": "mutable", + "inputs": [ + { + "name": "submissions", + "type": "variadic>", + "multi_arg": true + } + ], + "outputs": [] + }, + { + "name": "latestRoundData", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "variadic", + "multi_result": true + } + ] + }, + { + "name": "latestPriceFeed", + "mutability": "readonly", + "inputs": [ + { + "name": "from", + "type": "bytes" + }, + { + "name": "to", + "type": "bytes" + } + ], + "outputs": [ + { + "type": "u32" + }, + { + "type": "bytes" + }, + { + "type": "bytes" + }, + { + "type": "u64" + }, + { + "type": "BigUint" + }, + { + "type": "u8" + } + ] + }, + { + "name": "latestPriceFeedOptional", + "mutability": "readonly", + "inputs": [ + { + "name": "from", + "type": "bytes" + }, + { + "name": "to", + "type": "bytes" + } + ], + "outputs": [ + { + "type": "optional>", + "multi_result": true + } + ] + }, + { + "name": "setSubmissionCount", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "submission_count", + "type": "u32" + } + ], + "outputs": [] + }, + { + "name": "getOracles", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "variadic
", + "multi_result": true + } + ] + }, + { + "name": "setPairDecimals", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "from", + "type": "bytes" + }, + { + "name": "to", + "type": "bytes" + }, + { + "name": "decimals", + "type": "u8" + } + ], + "outputs": [] + }, + { + "name": "getPairDecimals", + "mutability": "readonly", + "inputs": [ + { + "name": "from", + "type": "bytes" + }, + { + "name": "to", + "type": "bytes" + } + ], + "outputs": [ + { + "type": "u8" + } + ] + }, + { + "name": "submission_count", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "u32" + } + ] + }, + { + "name": "pause", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, + { + "name": "unpause", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, + { + "name": "isPaused", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "bool" + } + ] + }, + { + "name": "stake", + "mutability": "mutable", + "payableInTokens": [ + "*" + ], + "inputs": [], + "outputs": [] + }, + { + "name": "unstake", + "mutability": "mutable", + "inputs": [ + { + "name": "unstake_amount", + "type": "BigUint" + } + ], + "outputs": [] + }, + { + "name": "voteSlashMember", + "mutability": "mutable", + "inputs": [ + { + "name": "member_to_slash", + "type": "Address" + } + ], + "outputs": [] + }, + { + "name": "cancelVoteSlashMember", + "mutability": "mutable", + "inputs": [ + { + "name": "member_to_slash", + "type": "Address" + } + ], + "outputs": [] + }, + { + "name": "slashMember", + "mutability": "mutable", + "inputs": [ + { + "name": "member_to_slash", + "type": "Address" + } + ], + "outputs": [] + } + ], + "events": [ + { + "identifier": "new_round", + "inputs": [ + { + "name": "from", + "type": "bytes", + "indexed": true + }, + { + "name": "to", + "type": "bytes", + "indexed": true + }, + { + "name": "epoch", + "type": "u64", + "indexed": true + }, + { + "name": "new_round_event", + "type": "NewRoundEvent" + } + ] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": { + "NewRoundEvent": { + "type": "struct", + "fields": [ + { + "name": "price", + "type": "BigUint" + }, + { + "name": "timestamp", + "type": "u64" + }, + { + "name": "decimals", + "type": "u8" + }, + { + "name": "block", + "type": "u64" + }, + { + "name": "epoch", + "type": "u64" + } + ] + }, + "PriceFeed": { + "type": "struct", + "fields": [ + { + "name": "round_id", + "type": "u32" + }, + { + "name": "from", + "type": "bytes" + }, + { + "name": "to", + "type": "bytes" + }, + { + "name": "timestamp", + "type": "u64" + }, + { + "name": "price", + "type": "BigUint" + }, + { + "name": "decimals", + "type": "u8" + } + ] + } + } +} diff --git a/price-aggregator/multiversx-price-aggregator-sc.wasm b/price-aggregator/multiversx-price-aggregator-sc.wasm new file mode 100755 index 00000000..5b6b4253 Binary files /dev/null and b/price-aggregator/multiversx-price-aggregator-sc.wasm differ diff --git a/price-aggregator/price-aggregator.abi.json b/price-aggregator/price-aggregator-deprecated.abi.json similarity index 100% rename from price-aggregator/price-aggregator.abi.json rename to price-aggregator/price-aggregator-deprecated.abi.json diff --git a/price-aggregator/price-aggregator.wasm b/price-aggregator/price-aggregator-deprecated.wasm similarity index 100% rename from price-aggregator/price-aggregator.wasm rename to price-aggregator/price-aggregator-deprecated.wasm diff --git a/price-aggregator/scenarios/deploy.scen.json b/price-aggregator/scenarios/deploy.scen.json new file mode 100644 index 00000000..78d381a0 --- /dev/null +++ b/price-aggregator/scenarios/deploy.scen.json @@ -0,0 +1,167 @@ +{ + "name": "deploy", + "steps": [ + { + "step": "setState", + "accounts": { + "address:aggregator-owner": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "address:oracle": { + "nonce": "0", + "balance": "100", + "storage": {} + }, + "address:oracle2": { + "nonce": "0", + "balance": "100", + "storage": {} + }, + "address:oracle3": { + "nonce": "0", + "balance": "100", + "storage": {} + }, + "address:oracle4": { + "nonce": "0", + "balance": "0", + "storage": {} + }, + "address:oracle5": { + "nonce": "0", + "balance": "0", + "storage": {} + } + }, + "newAddresses": [ + { + "creatorAddress": "address:aggregator-owner", + "creatorNonce": "0", + "newAddress": "sc:price_aggregator" + } + ] + }, + { + "step": "scDeploy", + "txId": "deploy", + "tx": { + "from": "address:aggregator-owner", + "contractCode": "file:../multiversx-price-aggregator-sc.wasm", + "value": "0", + "arguments": [ + "str:EGLD", + "20", + "10", + "3", + "3", + "address:oracle", + "address:oracle2", + "address:oracle3", + "address:oracle4", + "address:oracle5" + ], + "gasLimit": "20,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "oracle-set-pair", + "tx": { + "from": "address:aggregator-owner", + "to": "sc:price_aggregator", + "value": "0", + "function": "setPairDecimals", + "arguments": [ + "str:GWEI", + "str:BRIDGE", + "u8:6" + ], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "oracle-set-pair", + "tx": { + "from": "address:aggregator-owner", + "to": "sc:price_aggregator", + "value": "0", + "function": "setPairDecimals", + "arguments": [ + "str:GWEI", + "str:WEGLD-123456", + "u8:6" + ], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "unpause", + "tx": { + "from": "address:aggregator-owner", + "to": "sc:price_aggregator", + "value": "0", + "function": "unpause", + "arguments": [], + "gasLimit": "100,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "out": [], + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:aggregator-owner": { + "nonce": "4", + "balance": "0", + "storage": {} + }, + "sc:price_aggregator": { + "nonce": "0", + "balance": "0", + "storage": { + "str:submission_count": "3", + "str:decimals": "0", + "str:oracle_status.mapped|address:oracle": { + "0-total_submissions": "u64:0", + "1-accepted_submissions": "u64:0" + }, + "+": "" + }, + "code": "file:../multiversx-price-aggregator-sc.wasm" + }, + "+": {} + } + } + ] +} \ No newline at end of file diff --git a/price-aggregator/mandos/get_latest_price_feed.scen.json b/price-aggregator/scenarios/get_latest_price_feed.scen.json similarity index 94% rename from price-aggregator/mandos/get_latest_price_feed.scen.json rename to price-aggregator/scenarios/get_latest_price_feed.scen.json index 27ccdaa8..3b616063 100644 --- a/price-aggregator/mandos/get_latest_price_feed.scen.json +++ b/price-aggregator/scenarios/get_latest_price_feed.scen.json @@ -22,8 +22,9 @@ "1", "str:GWEI", "str:BRIDGE", + "0", "10", - "0" + "6" ] } }, @@ -47,8 +48,9 @@ "1", "str:GWEI", "str:BRIDGE", + "0", "10", - "0" + "6" ], "status": "0", "message": "", @@ -66,7 +68,7 @@ "function": "latestPriceFeedOptional", "arguments": [ "str:RAND-TOKEN", - "str:EGLD" + "str:WEGLD-123456" ], "gasLimit": "40,000,000", "gasPrice": "0" diff --git a/price-aggregator/mandos/oracle_gwei_in_eth_and_egld_submit.scen.json b/price-aggregator/scenarios/oracle_gwei_in_eth_and_egld_submit.scen.json similarity index 85% rename from price-aggregator/mandos/oracle_gwei_in_eth_and_egld_submit.scen.json rename to price-aggregator/scenarios/oracle_gwei_in_eth_and_egld_submit.scen.json index b8bf80d3..9c8c3599 100644 --- a/price-aggregator/mandos/oracle_gwei_in_eth_and_egld_submit.scen.json +++ b/price-aggregator/scenarios/oracle_gwei_in_eth_and_egld_submit.scen.json @@ -15,8 +15,10 @@ "function": "submit", "arguments": [ "str:GWEI", - "str:ETH", - "1" + "str:BRIDGE", + "u64:0", + "1", + "6" ], "gasLimit": "40,000,000", "gasPrice": "0" @@ -38,8 +40,10 @@ "function": "submit", "arguments": [ "str:GWEI", - "str:EGLD", - "10" + "str:WEGLD-123456", + "u64:0", + "10", + "6" ], "gasLimit": "40,000,000", "gasPrice": "0" diff --git a/price-aggregator/scenarios/oracle_stake.scen.json b/price-aggregator/scenarios/oracle_stake.scen.json new file mode 100644 index 00000000..0c7c402b --- /dev/null +++ b/price-aggregator/scenarios/oracle_stake.scen.json @@ -0,0 +1,66 @@ +{ + "name": "oracle stake", + "steps": [ + { + "step": "externalSteps", + "path": "deploy.scen.json" + }, + { + "step": "scCall", + "txId": "oracle-stake", + "tx": { + "from": "address:oracle", + "to": "sc:price_aggregator", + "value": "100", + "function": "stake", + "arguments": [], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "oracle-stake", + "tx": { + "from": "address:oracle2", + "to": "sc:price_aggregator", + "value": "100", + "function": "stake", + "arguments": [], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "oracle-stake", + "tx": { + "from": "address:oracle3", + "to": "sc:price_aggregator", + "value": "100", + "function": "stake", + "arguments": [], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + } + ] +} \ No newline at end of file diff --git a/price-aggregator/scenarios/oracle_submit.scen.json b/price-aggregator/scenarios/oracle_submit.scen.json new file mode 100644 index 00000000..53d53c45 --- /dev/null +++ b/price-aggregator/scenarios/oracle_submit.scen.json @@ -0,0 +1,84 @@ +{ + "name": "oracle submit", + "steps": [ + { + "step": "externalSteps", + "path": "oracle_stake.scen.json" + }, + { + "step": "scCall", + "txId": "oracle-submit", + "tx": { + "from": "address:oracle", + "to": "sc:price_aggregator", + "value": "0", + "function": "submit", + "arguments": [ + "str:GWEI", + "str:BRIDGE", + "u64:0", + "10", + "6" + ], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "oracle-submit", + "tx": { + "from": "address:oracle2", + "to": "sc:price_aggregator", + "value": "0", + "function": "submit", + "arguments": [ + "str:GWEI", + "str:BRIDGE", + "u64:0", + "10", + "6" + ], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "txId": "oracle-submit", + "tx": { + "from": "address:oracle3", + "to": "sc:price_aggregator", + "value": "0", + "function": "submit", + "arguments": [ + "str:GWEI", + "str:BRIDGE", + "u64:0", + "10", + "6" + ], + "gasLimit": "40,000,000", + "gasPrice": "0" + }, + "expect": { + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + } + ] +}