Skip to content
Draft
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion chain/vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ version = "=0.11.0"
path = "../core"

[dependencies.multiversx-chain-vm-executor]
version = "0.2.0"
# version = "0.2.0"
git = "https://github.com/multiversx/mx-vm-executor-rs"
branch = "rc/v1.7.next1"
2 changes: 2 additions & 0 deletions chain/vm/src/tx_mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod tx_managed_types;
mod tx_panic;
mod tx_result;
mod tx_result_calls;
mod tx_transfer_by_user_data;

pub use blockchain_update::BlockchainUpdate;
pub use tx_async_call_data::*;
Expand All @@ -36,6 +37,7 @@ pub use tx_managed_types::*;
pub use tx_panic::*;
pub use tx_result::*;
pub use tx_result_calls::*;
pub use tx_transfer_by_user_data::*;

#[cfg(feature = "wasm-incompatible")]
mod blockchain_rng;
Expand Down
45 changes: 45 additions & 0 deletions chain/vm/src/tx_mock/tx_transfer_by_user_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::{
tx_mock::TxInput,
types::{VMAddress, H256},
};

use super::{CallType, TxFunctionName, TxTokenTransfer};

#[derive(Debug, Clone)]
pub struct TranferByUserData {
pub from: VMAddress,
pub to: VMAddress,
pub token_transfers: Vec<TxTokenTransfer>,
pub func_name: TxFunctionName,
pub arguments: Vec<Vec<u8>>,
pub tx_hash: H256,
}

pub fn transfer_by_user_tx_input(
transfer_by_user_call: &TranferByUserData,
call_type: CallType,
) -> TxInput {
let mut egld_value = num_bigint::BigUint::default();
let mut esdt_values = Vec::new();

for transfer in &transfer_by_user_call.token_transfers {
if transfer.token_identifier.is_empty() && transfer.nonce == 0 {
egld_value += &transfer.value;
} else {
esdt_values.push(transfer.clone());
}
}
TxInput {
from: transfer_by_user_call.from.clone(),
to: transfer_by_user_call.to.clone(),
egld_value,
esdt_values,
func_name: transfer_by_user_call.func_name.clone(),
args: transfer_by_user_call.arguments.clone(),
call_type,
gas_limit: 1000,
gas_price: 0,
tx_hash: transfer_by_user_call.tx_hash.clone(),
..Default::default()
}
}
50 changes: 50 additions & 0 deletions chain/vm/src/vm_hooks/vh_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,18 @@ impl VMHooks for VMHooksDispatcher {
0
}

fn managed_multi_transfer_esdt_nft_execute_by_user(
&self,
user_handle: i32,
dst_handle: i32,
token_transfers_handle: i32,
gas_limit: i64,
function_handle: i32,
arguments_handle: i32,
) -> i32 {
panic!("Unavailable: managed_multi_transfer_esdt_nft_execute_by_user")
}

fn managed_transfer_value_execute(
&self,
dst_handle: i32,
Expand Down Expand Up @@ -1859,4 +1871,42 @@ impl VMHooks for VMHooksDispatcher {
) -> i32 {
panic!("Unavailable: elliptic_curve_get_values")
}

fn is_reserved_function_name(&self, name_handle: i32) -> i32 {
panic!("Unavailable: is_reserved_function_name")
}

fn managed_get_original_caller_addr(&self, destination_handle: i32) {
panic!("Unavailable: managed_get_original_caller_addr")
}

fn managed_get_relayer_addr(&self, destination_handle: i32) {
panic!("Unavailable: managed_get_relayer_addr")
}

fn managed_verify_secp256r1(
&self,
key_handle: i32,
message_handle: i32,
sig_handle: i32,
) -> i32 {
panic!("Unavailable: managed_verify_secp256r1")
}

fn managed_verify_blssignature_share(
&self,
key_handle: i32,
message_handle: i32,
sig_handle: i32,
) -> i32 {
panic!("Unavailable: managed_verify_blssignature_share")
}
fn managed_verify_blsaggregated_signature(
&self,
key_handle: i32,
message_handle: i32,
sig_handle: i32,
) -> i32 {
panic!("Unavailable: managed_verify_blsaggregated_signature")
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[[proxy]]
path = "src/forwarder_proxy.rs"

[[proxy]]
path = "../interact/src/forwarder_proxy.rs"
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,18 @@ where
.original_result()
}

pub fn forward_transf_exec_by_user_accept_funds<
Arg0: ProxyArg<ManagedAddress<Env::Api>>,
>(
self,
to: Arg0,
) -> TxTypedCall<Env, From, To, (), Gas, ()> {
self.wrapped_tx
.raw_call("forward_transf_exec_by_user_accept_funds")
.argument(&to)
.original_result()
}

pub fn forward_transf_execu_accept_funds_with_fees<
Arg0: ProxyArg<ManagedAddress<Env::Api>>,
Arg1: ProxyArg<BigUint<Env::Api>>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ pub trait ForwarderTransferExecuteModule {
.transfer_execute();
}

#[endpoint]
#[payable("*")]
fn forward_transf_exec_by_user_accept_funds(&self, to: ManagedAddress) {
let payments = self.call_value().all_esdt_transfers().clone_value();
let caller = self.blockchain().get_caller();
let _ = self.send_raw().multi_esdt_transfer_execute_by_user(
&caller,
&to,
&payments,
50_000_000u64,
&ManagedBuffer::from("accept_funds_echo_caller"),
&ManagedArgBuffer::new(),
);
}

#[endpoint]
#[payable("*")]
fn forward_transf_execu_accept_funds_with_fees(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ where
.original_result()
}

pub fn accept_funds_echo_caller(
self,
) -> TxTypedCall<Env, From, To, (), Gas, ManagedAddress<Env::Api>> {
self.wrapped_tx
.raw_call("accept_funds_echo_caller")
.original_result()
}

pub fn accept_funds_single_esdt_transfer(
self,
) -> TxTypedCall<Env, From, To, (), Gas, ()> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
////////////////////////////////////////////////////

// Init: 1
// Endpoints: 69
// Endpoints: 70
// Async Callback: 1
// Total number of exported functions: 71
// Total number of exported functions: 72

#![no_std]

Expand Down Expand Up @@ -42,6 +42,7 @@ multiversx_sc_wasm_adapter::endpoints! {
callback_data_at_index => callback_data_at_index
clear_callback_data => clear_callback_data
forward_transf_exec_accept_funds => forward_transf_exec_accept_funds
forward_transf_exec_by_user_accept_funds => forward_transf_exec_by_user_accept_funds
forward_transf_execu_accept_funds_with_fees => forward_transf_execu_accept_funds_with_fees
forward_transf_exec_accept_funds_twice => forward_transf_exec_accept_funds_twice
forward_transf_exec_accept_funds_return_values => forward_transf_exec_accept_funds_return_values
Expand Down
3 changes: 3 additions & 0 deletions contracts/feature-tests/composability/interact/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ path = "../../../../framework/base"
[dependencies.multiversx-sc-snippets]
version = "0.54.1"
path = "../../../../framework/snippets"

[features]
chain-simulator-tests = []
6 changes: 4 additions & 2 deletions contracts/feature-tests/composability/interact/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
chain_type = 'real'
gateway_uri = 'https://testnet-gateway.multiversx.com'
# chain_type = 'real'
# gateway_uri = 'https://testnet-gateway.multiversx.com'
chain_type = 'simulator'
gateway_uri = 'http://localhost:8085'
call_type = "LegacyAsync" # Sync / LegacyAsync / TransferExecute
# token_id = "CMPT-4e9332"
token_id = "EGLD"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use crate::{
use multiversx_sc_snippets::imports::*;

impl ComposabilityInteract {
pub async fn deploy_call_tree_contracts(&mut self, call_state: &CallState) {
pub async fn deploy_call_tree_contracts(
&mut self,
call_state: &CallState,
) -> (Vec<Bech32Address>, Vec<Bech32Address>) {
let vault_deploy_addresses = self.typed_sc_deploy_vault(call_state).await;
let forwarder_deploy_addresses = self.typed_sc_deploy_forwarder_queue(call_state).await;

Expand All @@ -27,6 +30,8 @@ impl ComposabilityInteract {

fwd.address = Some(address.to_address());
}

(vault_deploy_addresses, forwarder_deploy_addresses)
}

pub async fn typed_sc_deploy_vault(&mut self, call_state: &CallState) -> Vec<Bech32Address> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@ impl ComposabilityInteract {
.use_chain_simulator(config.use_chain_simulator())
.with_tracer(INTERACTOR_SCENARIO_TRACE_PATH)
.await;

interactor.set_current_dir_from_workspace("contracts/feature-tests/composability/interact");

let wallet_address = interactor.register_wallet(test_wallets::judy()).await;

interactor.generate_blocks_until_epoch(1).await.unwrap();

let forw_queue_code = BytesValue::interpret_from(
"mxsc:../forwarder-queue/output/forwarder-queue.mxsc.json",
&InterpreterContext::default(),
);

let vault_code = BytesValue::interpret_from(
"mxsc:../vault/output/vault.mxsc.json",
&InterpreterContext::default(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ mod comp_interact_config;
mod comp_interact_controller;
mod comp_interact_state;

mod forwarder_proxy;
mod forwarder_queue_proxy;
mod vault_proxy;

use call_tree::CallState;
use clap::Parser;
use comp_interact_controller::ComposabilityInteract;
use multiversx_sc_snippets::imports::*;

const FUNGIBLE_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("TOKEN-0000");

#[tokio::main]
async fn main() {
env_logger::init();
Expand All @@ -31,3 +35,36 @@ async fn main() {
None => {},
}
}

#[tokio::test]
#[cfg_attr(not(feature = "chain-simulator-tests"), ignore)]
pub async fn transf_exec_by_user_cs_test() {
let mut composability_interact = ComposabilityInteract::init().await;
let wallet_address = composability_interact.wallet_address.clone();

// set state for wallet address on chain simulator (esdt balance)

let call_state = CallState::simple_example_1();

let (vault, forwarder) = composability_interact
.deploy_call_tree_contracts(&call_state)
.await;

let logs = composability_interact
.interactor
.tx()
.from(wallet_address)
.to(forwarder.first().unwrap())
.typed(forwarder_proxy::ForwarderProxy)
.forward_transf_exec_by_user_accept_funds(vault.first().unwrap())
.single_esdt(
&FUNGIBLE_TOKEN_ID.to_token_identifier(),
0,
&BigUint::from(100u64),
)
.returns(ReturnsLogs)
.run()
.await;

println!("Logs: {logs:?}");
}
Loading