diff --git a/bridge-proxy/src/bridge-proxy.rs b/bridge-proxy/src/bridge-proxy.rs index 22d0ca63..98555ccf 100644 --- a/bridge-proxy/src/bridge-proxy.rs +++ b/bridge-proxy/src/bridge-proxy.rs @@ -35,8 +35,8 @@ pub trait BridgeProxyContract: let caller = self.blockchain().get_caller(); let payment = self.call_value().single_esdt(); require!( - caller == self.get_multi_transfer_address(), - "Only MultiTransfer can do deposits" + caller == self.get_esdt_safe_address(), + "Only EsdtSafe can do deposits" ); let next_tx_id = self.get_next_tx_id(); self.pending_transactions().insert(next_tx_id, eth_tx); diff --git a/bridge-proxy/tests/bridge_proxy_blackbox_test.rs b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs index 96174b23..c407a346 100644 --- a/bridge-proxy/tests/bridge_proxy_blackbox_test.rs +++ b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs @@ -128,10 +128,10 @@ impl BridgeProxyTestState { .nonce(1) .esdt_balance(TokenIdentifier::from(BRIDGE_TOKEN_ID), INITIAL_BALANCE) .account(MULTI_TRANSFER_ADDRESS) - .esdt_balance(TokenIdentifier::from(WBRIDGE_TOKEN_ID), INITIAL_BALANCE) - .esdt_balance(TokenIdentifier::from(BRIDGE_TOKEN_ID), INITIAL_BALANCE) .code(multi_transfer_code) .account(ESDT_SAFE_ADDRESS) + .esdt_balance(TokenIdentifier::from(WBRIDGE_TOKEN_ID), INITIAL_BALANCE) + .esdt_balance(TokenIdentifier::from(BRIDGE_TOKEN_ID), INITIAL_BALANCE) .code(esdt_safe_code); let roles = vec![ @@ -312,7 +312,7 @@ fn bridge_proxy_execute_crowdfunding_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -391,7 +391,7 @@ fn multiple_deposit_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx1, 1u64) @@ -404,7 +404,7 @@ fn multiple_deposit_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx2, 1u64) @@ -512,7 +512,7 @@ fn test_highest_tx_id() { for tx in &transactions { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(tx, 1u64) @@ -570,7 +570,7 @@ fn bridge_proxy_wrong_formatting_sc_call_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -649,7 +649,7 @@ fn bridge_proxy_wrong_endpoint_sc_call_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -730,7 +730,7 @@ fn bridge_proxy_wrong_args_sc_call_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -811,7 +811,7 @@ fn bridge_proxy_too_small_gas_sc_call_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -886,7 +886,7 @@ fn bridge_proxy_empty_endpoint_with_args_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -963,7 +963,7 @@ fn bridge_proxy_empty_endpoint_with_gas_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -1041,7 +1041,7 @@ fn bridge_proxy_refund_tx_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -1140,7 +1140,7 @@ fn bridge_proxy_double_execute_same_tx_test() { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) @@ -1221,7 +1221,7 @@ fn bridge_proxy_execute_1000_even_tx_test() { for _ in 1..101 { test.world .tx() - .from(MULTI_TRANSFER_ADDRESS) + .from(ESDT_SAFE_ADDRESS) .to(BRIDGE_PROXY_ADDRESS) .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) .deposit(ð_tx, 1u64) diff --git a/bridged-tokens-wrapper/src/lib.rs b/bridged-tokens-wrapper/src/lib.rs index 184a4eda..a2b1380e 100644 --- a/bridged-tokens-wrapper/src/lib.rs +++ b/bridged-tokens-wrapper/src/lib.rs @@ -205,6 +205,58 @@ pub trait BridgedTokensWrapper: new_payments } + /// Will wrap what it can, and send back the rest unchanged + #[payable("*")] + #[endpoint(wrapToken)] + fn wrap_token(&self) -> EsdtTokenPayment { + require!(self.not_paused(), "Contract is paused"); + let payment = self.call_value().single_esdt().clone(); + if payment.amount == 0 { + return payment.clone(); + } + + let payment_to_return = payment.clone(); + require!( + payment.token_nonce == 0, + "Only fungible tokens accepted for wrapping" + ); + let universal_token_id_mapper = + self.chain_specific_to_universal_mapping(&payment.token_identifier); + + // if there is chain specific -> universal mapping, then the token is whitelisted + if universal_token_id_mapper.is_empty() { + self.tx() + .to(ToCaller) + .esdt(payment_to_return.clone()) + .transfer(); + return payment_to_return.clone(); + } + + let universal_token_id = universal_token_id_mapper.get(); + self.require_tokens_have_set_decimals_num(&universal_token_id, &payment.token_identifier); + self.token_liquidity(&payment.token_identifier) + .update(|value| *value += &payment.amount.clone()); + let converted_amount = self.get_converted_amount( + &payment.token_identifier, + &universal_token_id, + payment.amount.clone(), + ); + + self.send() + .esdt_local_mint(&universal_token_id, 0, &converted_amount); + + let payment_to_return = + EsdtTokenPayment::new(universal_token_id.clone(), 0, converted_amount.clone()); + self.tx() + .to(ToCaller) + .esdt(payment_to_return.clone()) + .transfer(); + + self.wrap_tokens_event(universal_token_id, converted_amount); + + payment_to_return + } + #[payable("*")] #[endpoint(unwrapToken)] fn unwrap_token(&self, requested_token: TokenIdentifier) { diff --git a/bridged-tokens-wrapper/wasm/src/lib.rs b/bridged-tokens-wrapper/wasm/src/lib.rs index 62c77484..d5dc7c18 100644 --- a/bridged-tokens-wrapper/wasm/src/lib.rs +++ b/bridged-tokens-wrapper/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 16 +// Endpoints: 17 // Async Callback (empty): 1 -// Total number of exported functions: 19 +// Total number of exported functions: 20 #![no_std] @@ -27,6 +27,7 @@ multiversx_sc_wasm_adapter::endpoints! { blacklistToken => blacklist_token depositLiquidity => deposit_liquidity wrapTokens => wrap_tokens + wrapToken => wrap_token unwrapToken => unwrap_token unwrapTokenCreateTransaction => unwrap_token_create_transaction getUniversalBridgedTokenIds => universal_bridged_token_ids diff --git a/common/sc-proxies/src/bridged_tokens_wrapper_proxy.rs b/common/sc-proxies/src/bridged_tokens_wrapper_proxy.rs index 0610fc9b..65677a61 100644 --- a/common/sc-proxies/src/bridged_tokens_wrapper_proxy.rs +++ b/common/sc-proxies/src/bridged_tokens_wrapper_proxy.rs @@ -175,6 +175,15 @@ where .original_result() } + /// Will wrap what it can, and send back the rest unchanged + pub fn wrap_token( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .raw_call("wrapToken") + .original_result() + } + pub fn unwrap_token< Arg0: ProxyArg>, >( diff --git a/common/sc-proxies/src/esdt_safe_proxy.rs b/common/sc-proxies/src/esdt_safe_proxy.rs index 39207314..808c32e0 100644 --- a/common/sc-proxies/src/esdt_safe_proxy.rs +++ b/common/sc-proxies/src/esdt_safe_proxy.rs @@ -200,6 +200,22 @@ where .original_result() } + pub fn get_tokens< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + eth_tx: Arg0, + batch_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getTokens") + .argument(ð_tx) + .argument(&batch_id) + .original_result() + } + pub fn withdraw_refund_fees_for_ethereum< Arg0: ProxyArg>, Arg1: ProxyArg>, @@ -450,22 +466,6 @@ where .original_result() } - pub fn get_tokens< - Arg0: ProxyArg>, - Arg1: ProxyArg>, - >( - self, - token_id: Arg0, - amount: Arg1, - ) -> TxTypedCall { - self.wrapped_tx - .payment(NotPayable) - .raw_call("getTokens") - .argument(&token_id) - .argument(&amount) - .original_result() - } - pub fn init_supply< Arg0: ProxyArg>, Arg1: ProxyArg>, diff --git a/common/token-module/src/lib.rs b/common/token-module/src/lib.rs index 97c25073..faf1b5fb 100644 --- a/common/token-module/src/lib.rs +++ b/common/token-module/src/lib.rs @@ -162,56 +162,6 @@ pub trait TokenModule: self.token_whitelist().swap_remove(&token_id); } - #[endpoint(getTokens)] - fn get_tokens(&self, token_id: &TokenIdentifier, amount: &BigUint) -> bool { - let caller = self.blockchain().get_caller(); - require!( - caller == self.get_multi_transfer_address(), - "Only MultiTransfer can get tokens" - ); - - if !self.mint_burn_token(token_id).get() { - let total_balances_mapper = self.total_balances(token_id); - if &total_balances_mapper.get() >= amount { - total_balances_mapper.update(|total| { - *total -= amount; - }); - self.tx() - .to(ToCaller) - .single_esdt(token_id, 0, amount) - .transfer(); - - return true; - } else { - return false; - } - } - - let burn_balances_mapper = self.burn_balances(token_id); - let mint_balances_mapper = self.mint_balances(token_id); - if self.native_token(token_id).get() { - require!( - burn_balances_mapper.get() >= &mint_balances_mapper.get() + amount, - "Not enough burned tokens!" - ); - } - - let mint_executed = self.internal_mint(token_id, amount); - if !mint_executed { - return false; - } - self.tx() - .to(ToCaller) - .single_esdt(token_id, 0, amount) - .transfer(); - - mint_balances_mapper.update(|minted| { - *minted += amount; - }); - - true - } - #[only_owner] #[payable("*")] #[endpoint(initSupply)] diff --git a/esdt-safe/src/lib.rs b/esdt-safe/src/lib.rs index 340ee4ab..19b8de07 100644 --- a/esdt-safe/src/lib.rs +++ b/esdt-safe/src/lib.rs @@ -9,10 +9,13 @@ use core::convert::TryFrom; use core::ops::Deref; use eth_address::*; use fee_estimator_module::GWEI_STRING; -use transaction::{transaction_status::TransactionStatus, Transaction}; +use sc_proxies::{bridge_proxy_contract_proxy, bridged_tokens_wrapper_proxy}; +use transaction::{transaction_status::TransactionStatus, EthTransaction, Transaction, TxNonce}; const DEFAULT_MAX_TX_BATCH_SIZE: usize = 10; const DEFAULT_MAX_TX_BATCH_BLOCK_DURATION: u64 = 100; // ~10 minutes +const DEFAULT_GAS_LIMIT_FOR_REFUND_CALLBACK: u64 = 4_000_000; // 4 million +const GAS_LIMIT_ESDT_TRANSFER: u64 = 200_000; pub type PaymentsVec = ManagedVec>; @@ -439,6 +442,161 @@ pub trait EsdtSafe: EsdtTokenPayment::new(token_id, 0, refund_amount) } + #[endpoint(getTokens)] + fn get_tokens(&self, eth_tx: EthTransaction, batch_id: u64) { + let caller = self.blockchain().get_caller(); + require!( + caller == self.get_multi_transfer_address(), + "Only MultiTransfer can get tokens" + ); + + if !self.mint_burn_token(ð_tx.token_id).get() { + let total_balances_mapper = self.total_balances(ð_tx.token_id); + if &total_balances_mapper.get() >= ð_tx.amount { + total_balances_mapper.update(|total| { + *total -= ð_tx.amount; + }); + self.distribute_payments( + eth_tx.clone(), + EsdtTokenPayment::new(eth_tx.token_id, 0, eth_tx.amount), + batch_id, + ); + } + return; + } + + let burn_balances_mapper = self.burn_balances(ð_tx.token_id); + let mint_balances_mapper = self.mint_balances(ð_tx.token_id); + if self.native_token(ð_tx.token_id).get() { + require!( + burn_balances_mapper.get() >= &mint_balances_mapper.get() + ð_tx.amount, + "Not enough burned tokens!" + ); + } + + let mint_executed = self.internal_mint(ð_tx.token_id, ð_tx.amount); + if !mint_executed { + return; + } + + let bridged_tokens_wrapper_addr = self.get_bridged_tokens_wrapper_address(); + let wrapped_payment = self + .tx() + .to(bridged_tokens_wrapper_addr) + .typed(bridged_tokens_wrapper_proxy::BridgedTokensWrapperProxy) + .wrap_token() + .payment(EsdtTokenPayment::new( + eth_tx.token_id.clone(), + 0, + eth_tx.amount.clone(), + )) + .returns(ReturnsResult) + .sync_call(); + + self.distribute_payments( + eth_tx.clone(), + EsdtTokenPayment::new(wrapped_payment.token_identifier, 0, wrapped_payment.amount), + batch_id, + ); + + mint_balances_mapper.update(|minted| { + *minted += eth_tx.amount; + }); + } + + fn distribute_payments( + &self, + eth_tx: EthTransaction, + payment: EsdtTokenPayment, + batch_id: u64, + ) { + let bridge_proxy_addr = self.get_bridge_proxy_address(); + if self.blockchain().is_smart_contract(ð_tx.to) { + self.tx() + .to(bridge_proxy_addr.clone()) + .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) + .deposit(ð_tx.clone(), batch_id) + .single_esdt(&payment.token_identifier, 0, &payment.amount) + .gas(GAS_LIMIT_ESDT_TRANSFER) + .callback(self.callbacks().transfer_callback(eth_tx.clone(), batch_id)) + .with_extra_gas_for_callback(DEFAULT_GAS_LIMIT_FOR_REFUND_CALLBACK) + .register_promise(); + } else { + self.tx() + .to(ð_tx.to) + .single_esdt(&payment.token_identifier, 0, &payment.amount) + .gas(GAS_LIMIT_ESDT_TRANSFER) + .callback(self.callbacks().transfer_callback(eth_tx.clone(), batch_id)) + .with_extra_gas_for_callback(DEFAULT_GAS_LIMIT_FOR_REFUND_CALLBACK) + .register_promise(); + } + } + + #[promises_callback] + fn transfer_callback( + &self, + #[call_result] result: ManagedAsyncCallResult<()>, + tx: EthTransaction, + batch_id: u64, + ) { + let refund_payment = self.call_value().single_esdt(); + + match result { + ManagedAsyncCallResult::Ok(()) => { + self.transfer_performed_event( + batch_id, + tx.from, + tx.to, + tx.token_id, + tx.amount, + tx.tx_nonce, + ); + } + ManagedAsyncCallResult::Err(_) => { + self.unwrap_tokens(&tx.token_id, refund_payment.clone()); + let refund_tx = self.convert_to_refund_tx(tx.clone()); + self.add_to_batch(refund_tx); + + self.transfer_failed_frozen_destination_account_event(batch_id, tx.tx_nonce); + } + } + } + + fn convert_to_refund_tx(&self, eth_tx: EthTransaction) -> Transaction { + Transaction { + block_nonce: self.blockchain().get_block_nonce(), + nonce: eth_tx.tx_nonce, + from: eth_tx.from.as_managed_buffer().clone(), + to: eth_tx.to.as_managed_buffer().clone(), + token_identifier: eth_tx.token_id, + amount: eth_tx.amount, + is_refund_tx: true, + } + } + + fn unwrap_tokens( + &self, + requested_token: &TokenIdentifier, + payment: EsdtTokenPayment, + ) { + let bridged_tokens_wrapper_addr = self.get_bridged_tokens_wrapper_address(); + + if bridged_tokens_wrapper_addr.is_zero() { + return; + } + + if requested_token == &payment.token_identifier { + return; + } + + self.tx() + .to(bridged_tokens_wrapper_addr) + .typed(bridged_tokens_wrapper_proxy::BridgedTokensWrapperProxy) + .unwrap_token(requested_token) + .payment(payment) + .sync_call() + } + #[only_owner] #[endpoint(withdrawRefundFeesForEthereum)] fn withdraw_refund_fees_for_ethereum( @@ -690,6 +848,24 @@ pub trait EsdtSafe: #[indexed] tx_status: TransactionStatus, ); + #[event("transferPerformedEvent")] + fn transfer_performed_event( + &self, + #[indexed] batch_id: u64, + #[indexed] from: EthAddress, + #[indexed] to: ManagedAddress, + #[indexed] token_id: TokenIdentifier, + #[indexed] amount: BigUint, + #[indexed] tx_id: TxNonce, + ); + + #[event("transferFailedFrozenDestinationAccount")] + fn transfer_failed_frozen_destination_account_event( + &self, + #[indexed] batch_id: u64, + #[indexed] tx_id: u64, + ); + // storage #[storage_mapper("totalRefundAmount")] diff --git a/esdt-safe/wasm/src/lib.rs b/esdt-safe/wasm/src/lib.rs index e5efcd8c..f0d0049c 100644 --- a/esdt-safe/wasm/src/lib.rs +++ b/esdt-safe/wasm/src/lib.rs @@ -8,7 +8,8 @@ // Upgrade: 1 // Endpoints: 45 // Async Callback (empty): 1 -// Total number of exported functions: 48 +// Promise callbacks: 1 +// Total number of exported functions: 49 #![no_std] @@ -26,6 +27,7 @@ multiversx_sc_wasm_adapter::endpoints! { createTransaction => create_transaction createRefundTransaction => create_refund_transaction claimRefund => claim_refund + getTokens => get_tokens withdrawRefundFeesForEthereum => withdraw_refund_fees_for_ethereum withdrawTransactionFees => withdraw_transaction_fees computeTotalAmmountsFromIndex => compute_total_amounts_from_index @@ -42,7 +44,6 @@ multiversx_sc_wasm_adapter::endpoints! { distributeFees => distribute_fees addTokenToWhitelist => add_token_to_whitelist removeTokenFromWhitelist => remove_token_from_whitelist - getTokens => get_tokens initSupply => init_supply initSupplyMintBurn => init_supply_mint_burn getAllKnownTokens => token_whitelist @@ -65,6 +66,7 @@ multiversx_sc_wasm_adapter::endpoints! { pause => pause_endpoint unpause => unpause_endpoint isPaused => paused_status + transfer_callback => transfer_callback ) } diff --git a/multi-transfer-esdt/scenarios/basic_transfer_test.scen.json b/multi-transfer-esdt/scenarios/basic_transfer_test.scen.json new file mode 100644 index 00000000..ab26e0c8 --- /dev/null +++ b/multi-transfer-esdt/scenarios/basic_transfer_test.scen.json @@ -0,0 +1,272 @@ +{ + "steps": [ + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "address:owner", + "creatorNonce": "1", + "newAddress": "sc:multisig" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "address:owner", + "contractCode": "mxsc:../common/mock-contracts/mock-multisig/output/mock-multisig.mxsc.json", + "arguments": [ + "0x00000000000000000500657364742d736166655f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x000000000000000005006d756c74692d7472616e736665725f5f5f5f5f5f5f5f", + "0x000000000000000005006272696467652d70726f78795f5f5f5f5f5f5f5f5f5f", + "0x00000000000000000500627269646765642d746f6b656e732d77726170706572", + "0x0000000000000000050070726963652d61676772656761746f725f5f5f5f5f5f", + "0x03e8", + "0x01f4", + "0x02", + "0x72656c61796572315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x72656c61796572325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "sc:multisig", + "creatorNonce": "0", + "newAddress": "sc:multi-transfer" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "sc:multisig", + "contractCode": "mxsc:output/multi-transfer-esdt.mxsc.json", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "sc:multisig", + "creatorNonce": "1", + "newAddress": "sc:bridge-proxy" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "sc:multisig", + "contractCode": "mxsc:../bridge-proxy/output/bridge-proxy.mxsc.json", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "sc:multisig", + "creatorNonce": "2", + "newAddress": "sc:esdt-safe" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "sc:multisig", + "contractCode": "mxsc:../common/mock-contracts/mock-esdt-safe/output/mock-esdt-safe.mxsc.json", + "arguments": [ + "0x0249f0" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "sc:multisig", + "creatorNonce": "3", + "newAddress": "sc:bridged-tokens-wrapper" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "sc:multisig", + "contractCode": "mxsc:../bridged-tokens-wrapper/output/bridged-tokens-wrapper.mxsc.json", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "sc:multisig", + "to": "sc:esdt-safe", + "function": "addTokenToWhitelist", + "arguments": [ + "0x4252494447452d313233343536", + "0x425249444745", + "0x01", + "0x", + "0x", + "0x", + "0x", + "0x0249f0" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "sc:multisig", + "to": "sc:esdt-safe", + "esdtValue": [ + { + "tokenIdentifier": "0x544f4b454e", + "value": "100000000000000" + } + ], + "function": "addTokenToWhitelist", + "arguments": [ + "0x544f4b454e", + "0x544f4b454e", + "0x", + "0x01", + "0x5af3107a4000", + "0x", + "0x", + "0x0249f0" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "sc:multisig", + "to": "sc:multi-transfer", + "function": "setMaxBridgedAmount", + "arguments": [ + "0x544f4b454e", + "0x5af3107a3fff" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "sc:multisig", + "to": "sc:esdt-safe", + "function": "unpause", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "sc:multisig", + "to": "sc:bridged-tokens-wrapper", + "function": "unpause", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "sc:multisig", + "to": "sc:bridge-proxy", + "function": "unpause", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "sc:multisig", + "to": "sc:multi-transfer", + "function": "batchTransferEsdtToken", + "arguments": [ + "0x01", + "0x000000000000000000000000000000000000000075736572315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0000000d4252494447452d3132333435360000000201f400000000000000010100000003616464" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} diff --git a/multi-transfer-esdt/src/lib.rs b/multi-transfer-esdt/src/lib.rs index 8aa2291c..c0d27afd 100644 --- a/multi-transfer-esdt/src/lib.rs +++ b/multi-transfer-esdt/src/lib.rs @@ -47,8 +47,6 @@ pub trait MultiTransferEsdt: batch_id: u64, transfers: MultiValueEncoded>, ) { - let mut valid_payments_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(); @@ -57,28 +55,14 @@ pub trait MultiTransferEsdt: let safe_address = self.get_esdt_safe_address(); for eth_tx in transfers { - // let token_roles = self - // .blockchain() - // .get_esdt_local_roles(ð_tx.token_id.clone()); - // if token_roles.has_role(&EsdtLocalRole::Transfer) { - // self.add_eth_tx_to_refund_tx_list(eth_tx.clone(), &mut refund_tx_list); - // self.token_with_transfer_role_event(eth_tx.token_id); - // continue; - // } - - let is_success: bool = self + self .tx() .to(safe_address.clone()) .typed(esdt_safe_proxy::EsdtSafeProxy) - .get_tokens(ð_tx.token_id, ð_tx.amount) + .get_tokens(ð_tx, batch_id) .returns(ReturnsResult) .sync_call(); - if !is_success { - self.add_eth_tx_to_refund_tx_list(eth_tx, &mut refund_tx_list); - continue; - } - let universal_token = self.get_universal_token(eth_tx.clone()); if eth_tx.to.is_zero() { @@ -118,14 +102,8 @@ pub trait MultiTransferEsdt: eth_tx.tx_nonce, ); } - - valid_tx_list.push(eth_tx.clone()); - valid_payments_list.push(EsdtTokenPayment::new(eth_tx.token_id, 0, eth_tx.amount)); } - let payments_after_wrapping = self.wrap_tokens(valid_payments_list); - self.distribute_payments(valid_tx_list, payments_after_wrapping, batch_id); - self.add_multiple_tx_to_batch(&refund_tx_list); } diff --git a/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs b/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs index 1c484968..d19d30ec 100644 --- a/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs +++ b/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs @@ -729,6 +729,8 @@ fn basic_transfer_test() { let mut state = MultiTransferTestState::new(); let token_amount = BigUint::from(500u64); + state.world.start_trace(); + state.deploy_contracts(); state.config_multi_transfer(); @@ -766,6 +768,10 @@ fn basic_transfer_test() { .world .check_account(USER1_ADDRESS) .esdt_balance(BRIDGE_TOKEN_ID, token_amount); + + state + .world + .write_scenario_trace("scenarios/basic_transfer_test.scen.json"); } #[test] @@ -1322,21 +1328,21 @@ fn add_refund_batch_test_should_work() { BigUint::zero(), ); - state - .world - .tx() - .from(MULTISIG_ADDRESS) - .to(MULTI_TRANSFER_ADDRESS) - .typed(multi_transfer_esdt_proxy::MultiTransferEsdtProxy) - .move_refund_batch_to_safe() - .run(); + // state + // .world + // .tx() + // .from(MULTISIG_ADDRESS) + // .to(MULTI_TRANSFER_ADDRESS) + // .typed(multi_transfer_esdt_proxy::MultiTransferEsdtProxy) + // .move_refund_batch_to_safe() + // .run(); state.check_balances_on_safe( TOKEN_TICKER, BigUint::from(MAX_AMOUNT) - fee, BigUint::zero(), BigUint::zero(), - ); + );2 } #[test] diff --git a/multi-transfer-esdt/tests/scenario_go_test.rs b/multi-transfer-esdt/tests/scenario_go_test.rs index 0f043e4a..e9a81fa9 100644 --- a/multi-transfer-esdt/tests/scenario_go_test.rs +++ b/multi-transfer-esdt/tests/scenario_go_test.rs @@ -4,6 +4,11 @@ fn world() -> ScenarioWorld { ScenarioWorld::vm_go() } +#[test] +fn basic_transfer_test_go() { + world().run("scenarios/basic_transfer_test.scen.json"); +} + #[test] #[ignore] //Ignore for now fn batch_transfer_both_executed_go() {