diff --git a/esdt-safe/src/lib.rs b/esdt-safe/src/lib.rs index 327ec158..02e76113 100644 --- a/esdt-safe/src/lib.rs +++ b/esdt-safe/src/lib.rs @@ -20,8 +20,8 @@ pub type PaymentsVec = ManagedVec>; #[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, Clone, ManagedVecItem, PartialEq)] pub struct RefundInfo { pub address: ManagedAddress, - pub initial_batch_id: u64, - pub initial_nonce: u64 + pub initial_batch_id: u64, + pub initial_nonce: u64, } #[multiversx_sc::contract] @@ -80,8 +80,8 @@ pub trait EsdtSafe: .set(&fee_estimator_contract_address); self.multi_transfer_contract_address() .set(&multi_transfer_contract_address); - self.bridge_proxy_contract_address(). - set(&bridge_proxy_contract_address); + self.bridge_proxy_contract_address() + .set(&bridge_proxy_contract_address); self.eth_tx_gas_limit().set(ð_tx_gas_limit); @@ -246,7 +246,7 @@ pub trait EsdtSafe: }); } else { self.total_balances(&refund_token_id).update(|total| { - *total -= &actual_bridged_amount; + *total += &actual_bridged_amount; }); } } @@ -304,7 +304,11 @@ pub trait EsdtSafe: sc_panic!("Cannot specify a refund address from this caller"); } } - OptionalValue::None => RefundInfo{ address: caller, initial_batch_id: 0, initial_nonce: 0}, + OptionalValue::None => RefundInfo { + address: caller, + initial_batch_id: 0, + initial_nonce: 0, + }, }; self.accumulated_transaction_fees(&payment_token) @@ -364,7 +368,6 @@ pub trait EsdtSafe: refund_info.initial_nonce, ); } - } /// Claim funds for failed MultiversX -> Ethereum transactions. diff --git a/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs b/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs index 70f0cc7e..62482ff5 100644 --- a/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs +++ b/multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs @@ -42,6 +42,7 @@ use transaction::{CallData, EthTransaction}; const UNIVERSAL_TOKEN_IDENTIFIER: TestTokenIdentifier = TestTokenIdentifier::new("UNIV-abc123"); const BRIDGE_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("BRIDGE-123456"); const WRAPPED_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("WRAPPED-123456"); +const TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("TOKEN"); const USER_ETHEREUM_ADDRESS: &[u8] = b"0x0102030405060708091011121314151617181920"; @@ -69,6 +70,7 @@ const USER1_ADDRESS: TestAddress = TestAddress::new("user1"); const USER2_ADDRESS: TestAddress = TestAddress::new("user2"); const ESDT_SAFE_ETH_TX_GAS_LIMIT: u64 = 150_000; +const MAX_AMOUNT: u64 = 100_000_000_000_000u64; const BALANCE: &str = "2,000,000"; @@ -108,6 +110,7 @@ impl MultiTransferTestState { .account(OWNER_ADDRESS) .nonce(1) .esdt_balance(BRIDGE_TOKEN_ID, 1001u64) + .esdt_balance(TOKEN_ID, MAX_AMOUNT) .esdt_balance(WRAPPED_TOKEN_ID, 1001u64) .esdt_balance(UNIVERSAL_TOKEN_IDENTIFIER, 1001u64) .account(USER1_ADDRESS) @@ -242,6 +245,36 @@ impl MultiTransferTestState { ) .run(); + self.world + .tx() + .from(OWNER_ADDRESS) + .to(ESDT_SAFE_ADDRESS) + .typed(esdt_safe_proxy::EsdtSafeProxy) + .add_token_to_whitelist( + TokenIdentifier::from_esdt_bytes("TOKEN"), + "TOKEN", + false, + true, + BigUint::from(MAX_AMOUNT), + BigUint::zero(), + BigUint::zero(), + OptionalValue::Some(BigUint::from(ESDT_SAFE_ETH_TX_GAS_LIMIT)), + ) + .single_esdt( + &TokenIdentifier::from_esdt_bytes("TOKEN"), + 0, + &BigUint::from(MAX_AMOUNT), + ) + .run(); + + self.world + .tx() + .from(OWNER_ADDRESS) + .to(MULTI_TRANSFER_ADDRESS) + .typed(multi_transfer_proxy::MultiTransferEsdtProxy) + .set_max_bridged_amount(TOKEN_ID, MAX_AMOUNT - 1) + .run(); + self.world .tx() .from(OWNER_ADDRESS) @@ -436,6 +469,55 @@ impl MultiTransferTestState { ) .run(); } + + fn check_balances_on_safe( + &mut self, + total_supply: BigUint, + total_minted: BigUint, + total_burned: BigUint, + ) { + let actual_total_supply = self + .world + .query() + .to(ESDT_SAFE_ADDRESS) + .typed(esdt_safe_proxy::EsdtSafeProxy) + .total_balances(TOKEN_ID) + .returns(ReturnsResult) + .run(); + + assert_eq!( + actual_total_supply, total_supply, + "Total supply balance is wrong" + ); + let actual_total_burned = self + .world + .query() + .to(ESDT_SAFE_ADDRESS) + .typed(esdt_safe_proxy::EsdtSafeProxy) + .burn_balances(TOKEN_ID) + .returns(ReturnsResult) + .run(); + + assert_eq!( + actual_total_burned, total_burned, + "Total burned balance is wrong" + ); + + let actual_total_minted = self + .world + .query() + .to(ESDT_SAFE_ADDRESS) + .typed(esdt_safe_proxy::EsdtSafeProxy) + .mint_balances(TOKEN_ID) + .returns(ReturnsResult) + .run(); + + assert_eq!( + actual_total_minted, total_minted, + "Total minted balance is wrong" + ); + } + fn deploy_contracts(&mut self) { self.multi_transfer_deploy(); self.bridge_proxy_deploy(); @@ -777,10 +859,7 @@ fn test_unwrap_token_create_transaction_insufficient_liquidity() { .from(USER1_ADDRESS) .to(BRIDGED_TOKENS_WRAPPER_ADDRESS) .typed(bridged_tokens_wrapper_proxy::BridgedTokensWrapperProxy) - .unwrap_token_create_transaction( - WRAPPED_TOKEN_ID, - EthAddress::zero(), - ) + .unwrap_token_create_transaction(WRAPPED_TOKEN_ID, EthAddress::zero()) .egld_or_single_esdt( &EgldOrEsdtTokenIdentifier::esdt(UNIVERSAL_TOKEN_IDENTIFIER), 0u64, @@ -842,3 +921,63 @@ fn test_unwrap_token_create_transaction_amount_zero() { .returns(ExpectError(ERROR, "Must pay more than 0 tokens!")) .run(); } + +#[test] +fn add_refund_batch_test() { + let mut state = MultiTransferTestState::new(); + + state.multi_transfer_deploy(); + state.bridge_proxy_deploy(); + state.safe_deploy(Address::zero()); + state.bridged_tokens_wrapper_deploy(); + state.config_multi_transfer(); + + let eth_tx = EthTransaction { + from: EthAddress::zero(), + to: ManagedAddress::from(USER1_ADDRESS.eval_to_array()), + token_id: TokenIdentifier::from(TOKEN_ID), + amount: BigUint::from(MAX_AMOUNT), + tx_nonce: 1u64, + call_data: ManagedOption::none(), + }; + + let mut transfers: MultiValueEncoded> = + MultiValueEncoded::new(); + transfers.push(eth_tx.clone()); + + let fee = state + .world + .query() + .to(ESDT_SAFE_ADDRESS) + .typed(esdt_safe_proxy::EsdtSafeProxy) + .calculate_required_fee(TOKEN_ID) + .returns(ReturnsResult) + .run(); + + state.check_balances_on_safe(BigUint::from(MAX_AMOUNT), BigUint::zero(), BigUint::zero()); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(MULTI_TRANSFER_ADDRESS) + .typed(multi_transfer_proxy::MultiTransferEsdtProxy) + .batch_transfer_esdt_token(1u32, transfers) + .run(); + state.check_balances_on_safe(BigUint::zero(), BigUint::zero(), BigUint::zero()); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(MULTI_TRANSFER_ADDRESS) + .typed(multi_transfer_proxy::MultiTransferEsdtProxy) + .move_refund_batch_to_safe() + .run(); + + state.check_balances_on_safe( + BigUint::from(MAX_AMOUNT) - fee, + BigUint::zero(), + BigUint::zero(), + ); +}