From 8df26a424fcffa4926e6fcc1054513ca57b0c146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Costin=20Caraba=C8=99?= Date: Wed, 30 Oct 2024 17:35:58 +0200 Subject: [PATCH 1/2] paymaster: transfer_callback: handle payments in case of fail --- contracts/paymaster/src/forward_call.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/contracts/paymaster/src/forward_call.rs b/contracts/paymaster/src/forward_call.rs index 3e22d30d..1f1dbea7 100644 --- a/contracts/paymaster/src/forward_call.rs +++ b/contracts/paymaster/src/forward_call.rs @@ -21,8 +21,11 @@ pub trait ForwardCall { .to(&dest) .raw_call(endpoint_name) .arguments_raw(endpoint_args.to_arg_buffer()) - .payment(payments) - .callback(self.callbacks().transfer_callback(original_caller)) + .payment(payments.clone()) + .callback( + self.callbacks() + .transfer_callback(original_caller, payments), + ) .async_call_and_exit(); } @@ -30,6 +33,7 @@ pub trait ForwardCall { fn transfer_callback( &self, original_caller: ManagedAddress, + payments: PaymentsVec, #[call_result] result: ManagedAsyncCallResult>, ) -> MultiValueEncoded { let back_transfers = self.blockchain().get_back_transfers(); @@ -54,6 +58,11 @@ pub trait ForwardCall { return_values } ManagedAsyncCallResult::Err(err) => { + let egld_value = self.call_value().egld_value(); + // Send the resulted tokens to the original caller + self.tx().to(&original_caller).payment(&payments).transfer(); + self.tx().to(&original_caller).egld(egld_value).transfer(); + let mut err_result = MultiValueEncoded::new(); err_result.push(ManagedBuffer::new_from_bytes(ERR_CALLBACK_MSG)); err_result.push(err.err_msg); From 4fe9924e929aa5b4548e94a41e66b9388f7ac83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Costin=20Caraba=C8=99?= Date: Mon, 11 Nov 2024 13:59:23 +0200 Subject: [PATCH 2/2] paymaster: handle payments in case of fail unit test --- .../tests/paymaster_blackbox_test.rs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/contracts/paymaster/tests/paymaster_blackbox_test.rs b/contracts/paymaster/tests/paymaster_blackbox_test.rs index b61d6487..9736b508 100644 --- a/contracts/paymaster/tests/paymaster_blackbox_test.rs +++ b/contracts/paymaster/tests/paymaster_blackbox_test.rs @@ -378,3 +378,61 @@ fn test_forward_call_fails_wegld_0_amount() { // Caller has the original balance state.check_esdt_balance(CALLER_ADDRESS_EXPR, WEGLD_TOKEN_ID_EXPR, BALANCE); } + +#[test] +fn test_forward_call_fails_check_amounts() { + let mut state = PaymasterTestState::new(); + state.deploy_paymaster_contract(); + state.deploy_wegld_contract(); + + state.check_esdt_balance(CALLER_ADDRESS_EXPR, FEE_TOKEN_ID_EXPR, BALANCE); + state.check_esdt_balance(CALLER_ADDRESS_EXPR, WEGLD_TOKEN_ID_EXPR, BALANCE); + + let mut payments: MultiEsdtPayment = MultiEsdtPayment::new(); + payments.push(EsdtTokenPayment::new( + TokenIdentifier::from(FEE_TOKEN_ID_EXPR), + 0, + BigUint::from(FEE_AMOUNT), + )); + + let sent_amount = 1_000u64; + payments.push(EsdtTokenPayment::new( + TokenIdentifier::from(WEGLD_TOKEN_ID), + 0, + BigUint::from(sent_amount), + )); + + state + .world + .tx() + .from(OWNER_ADDRESS_EXPR) + .to(CALLEE_SC_WEGLD_ADDRESS_EXPR) + .typed(wegld_proxy::EgldEsdtSwapProxy) + .pause_endpoint() + .run(); + + // Call fails because wrong WEGLD token provided + state + .world + .tx() + .from(CALLER_ADDRESS_EXPR) + .to(PAYMASTER_ADDRESS_EXPR) + .typed(paymaster_proxy::PaymasterContractProxy) + .forward_execution( + RELAYER_ADDRESS_EXPR, + CALLEE_SC_WEGLD_ADDRESS_EXPR, + 100u64, + UNWRAP_ENDPOINT_NAME, + MultiValueEncoded::new(), + ) + .multi_esdt(payments) + .run(); + + // Fee is kept by the relayer + let new_fee_amount: u64 = 99_980_000; + state.check_esdt_balance(RELAYER_ADDRESS_EXPR, FEE_TOKEN_ID_EXPR, FEE_AMOUNT); + state.check_esdt_balance(CALLER_ADDRESS_EXPR, FEE_TOKEN_ID_EXPR, new_fee_amount); + + // Caller has the original balance + state.check_esdt_balance(CALLER_ADDRESS_EXPR, WEGLD_TOKEN_ID_EXPR, BALANCE); +}