From 13d34c7aeebb33a46874e2149d30435882b249ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Costin=20Caraba=C8=99?= Date: Mon, 9 Dec 2024 15:29:04 +0200 Subject: [PATCH 1/2] bridge-proxy: Clear storages after refund --- bridge-proxy/src/bridge-proxy.rs | 46 ++++++++----------- .../tests/bridge_proxy_blackbox_test.rs | 21 ++++++++- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/bridge-proxy/src/bridge-proxy.rs b/bridge-proxy/src/bridge-proxy.rs index 97e28401..bb041f3b 100644 --- a/bridge-proxy/src/bridge-proxy.rs +++ b/bridge-proxy/src/bridge-proxy.rs @@ -9,7 +9,7 @@ use transaction::{CallData, EthTransaction}; const MIN_GAS_LIMIT_FOR_SC_CALL: u64 = 10_000_000; const MAX_GAS_LIMIT_FOR_SC_CALL: u64 = 249999999; const DEFAULT_GAS_LIMIT_FOR_REFUND_CALLBACK: u64 = 20_000_000; // 20 million -const DELAY_BEFORE_OWNER_CAN_CANCEL_TRANSACTION: u64 = 300; +const DELAY_BEFORE_OWNER_CAN_REFUND_TRANSACTION: u64 = 300; #[multiversx_sc::contract] pub trait BridgeProxyContract: @@ -103,38 +103,28 @@ pub trait BridgeProxyContract: tx_call.register_promise(); } - // TODO: will activate endpoint in a future release - // #[endpoint(cancel)] - fn cancel(&self, tx_id: usize) { - let tx_start_round = self.ongoing_execution(tx_id).get(); - let current_block_round = self.blockchain().get_block_round(); - require!( - current_block_round - tx_start_round > DELAY_BEFORE_OWNER_CAN_CANCEL_TRANSACTION, - "Transaction can't be cancelled yet" - ); - - let tx = self.get_pending_transaction_by_id(tx_id); - let payment = self.payments(tx_id).get(); - self.tx().to(tx.to).payment(payment).transfer(); - self.cleanup_transaction(tx_id); - } - #[promises_callback] fn execution_callback(&self, #[call_result] result: ManagedAsyncCallResult<()>, tx_id: usize) { if result.is_err() { self.add_pending_tx_to_refund(tx_id); } - self.cleanup_transaction(tx_id); + self.pending_transactions().remove(&tx_id); } #[endpoint(executeRefundTransaction)] fn execute_refund_transaction(&self, tx_id: usize) { - let tx = self.get_refund_transaction_by_id(tx_id); + let tx_start_round = self.ongoing_execution(tx_id).get(); + let current_block_round = self.blockchain().get_block_round(); + require!( + current_block_round - tx_start_round > DELAY_BEFORE_OWNER_CAN_REFUND_TRANSACTION, + "Refund executed too early!" + ); + let tx = self.get_refund_transaction_by_id(tx_id); let esdt_safe_contract_address = self.get_esdt_safe_address(); - let unwrapped_token = self.unwrap_token(&tx.token_id, tx_id); let batch_id = self.batch_id(tx_id).get(); + self.tx() .to(esdt_safe_contract_address) .typed(esdt_safe_proxy::EsdtSafeProxy) @@ -152,6 +142,8 @@ pub trait BridgeProxyContract: &unwrapped_token.amount, ) .sync_call(); + + self.finish_refund(tx_id); } fn unwrap_token(&self, requested_token: &TokenIdentifier, tx_id: usize) -> EsdtTokenPayment { @@ -188,7 +180,14 @@ pub trait BridgeProxyContract: fn finish_execute_gracefully(&self, tx_id: usize) { self.add_pending_tx_to_refund(tx_id); - self.cleanup_transaction(tx_id); + self.pending_transactions().remove(&tx_id); + } + + fn finish_refund(&self, tx_id: usize) { + self.refund_transactions().remove(&tx_id); + self.ongoing_execution(tx_id).clear(); + self.payments(tx_id).clear(); + self.batch_id(tx_id).clear(); } fn add_pending_tx_to_refund(&self, tx_id: usize) { @@ -196,11 +195,6 @@ pub trait BridgeProxyContract: self.refund_transactions().insert(tx_id, tx); } - fn cleanup_transaction(&self, tx_id: usize) { - self.pending_transactions().remove(&tx_id); - self.ongoing_execution(tx_id).clear(); - } - fn get_next_tx_id(&self) -> usize { let mut next_tx_id = self.highest_tx_id().get(); next_tx_id += 1; diff --git a/bridge-proxy/tests/bridge_proxy_blackbox_test.rs b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs index 5156702b..ec8dd809 100644 --- a/bridge-proxy/tests/bridge_proxy_blackbox_test.rs +++ b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs @@ -33,7 +33,7 @@ use multiversx_sc_scenario::{ scenario_model::*, ContractInfo, ScenarioWorld, }; -use multiversx_sc_scenario::{ExpectValue, ScenarioTxRun}; +use multiversx_sc_scenario::{ExpectError, ExpectValue, ScenarioTxRun}; use eth_address::*; use mock_proxies::mock_multisig_proxy; @@ -43,6 +43,7 @@ use transaction::{CallData, EthTransaction}; const BRIDGE_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("BRIDGE-123456"); const WBRIDGE_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("WBRIDGE-123456"); +const DELAY_BEFORE_OWNER_CAN_REFUND_TRANSACTION: u64 = 300; const GAS_LIMIT: u64 = 10_000_000; const TOO_SMALL_GAS_LIMIT: u64 = 1_000_000; @@ -238,6 +239,9 @@ impl BridgeProxyTestState { self } + fn set_block_round(&mut self, block_round_expr: u64) { + self.world.current_block().block_round(block_round_expr); + } } #[test] @@ -951,6 +955,17 @@ fn bridge_proxy_refund_tx_test() { .check_account(USER_ADDRESS) .esdt_balance(BRIDGE_TOKEN_ID, BigUint::from(INITIAL_BALANCE)); + test.world + .tx() + .from(USER_ADDRESS) + .to(BRIDGE_PROXY_ADDRESS) + .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) + .execute_refund_transaction(1u32) + .returns(ExpectError(4, "Refund executed too early!")) + .run(); + + test.set_block_round(DELAY_BEFORE_OWNER_CAN_REFUND_TRANSACTION + 1); + test.world .tx() .from(USER_ADDRESS) @@ -962,4 +977,8 @@ fn bridge_proxy_refund_tx_test() { test.world .check_account(BRIDGE_PROXY_ADDRESS) .esdt_balance(BRIDGE_TOKEN_ID, BigUint::zero()); + + test.world + .check_account(BRIDGE_PROXY_ADDRESS) + .check_storage("str:highestTxId", "1"); } From 5f05e2e2ba412a9660071af8718845e10c375a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Costin=20Caraba=C8=99?= Date: Mon, 9 Dec 2024 17:52:49 +0200 Subject: [PATCH 2/2] bridge-proxy: Remove cooldown from refund --- bridge-proxy/src/bridge-proxy.rs | 10 +--------- bridge-proxy/tests/bridge_proxy_blackbox_test.rs | 11 ----------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/bridge-proxy/src/bridge-proxy.rs b/bridge-proxy/src/bridge-proxy.rs index bb041f3b..d97d8050 100644 --- a/bridge-proxy/src/bridge-proxy.rs +++ b/bridge-proxy/src/bridge-proxy.rs @@ -9,7 +9,6 @@ use transaction::{CallData, EthTransaction}; const MIN_GAS_LIMIT_FOR_SC_CALL: u64 = 10_000_000; const MAX_GAS_LIMIT_FOR_SC_CALL: u64 = 249999999; const DEFAULT_GAS_LIMIT_FOR_REFUND_CALLBACK: u64 = 20_000_000; // 20 million -const DELAY_BEFORE_OWNER_CAN_REFUND_TRANSACTION: u64 = 300; #[multiversx_sc::contract] pub trait BridgeProxyContract: @@ -113,13 +112,6 @@ pub trait BridgeProxyContract: #[endpoint(executeRefundTransaction)] fn execute_refund_transaction(&self, tx_id: usize) { - let tx_start_round = self.ongoing_execution(tx_id).get(); - let current_block_round = self.blockchain().get_block_round(); - require!( - current_block_round - tx_start_round > DELAY_BEFORE_OWNER_CAN_REFUND_TRANSACTION, - "Refund executed too early!" - ); - let tx = self.get_refund_transaction_by_id(tx_id); let esdt_safe_contract_address = self.get_esdt_safe_address(); let unwrapped_token = self.unwrap_token(&tx.token_id, tx_id); @@ -184,10 +176,10 @@ pub trait BridgeProxyContract: } fn finish_refund(&self, tx_id: usize) { - self.refund_transactions().remove(&tx_id); self.ongoing_execution(tx_id).clear(); self.payments(tx_id).clear(); self.batch_id(tx_id).clear(); + self.refund_transactions().remove(&tx_id); } fn add_pending_tx_to_refund(&self, tx_id: usize) { diff --git a/bridge-proxy/tests/bridge_proxy_blackbox_test.rs b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs index ec8dd809..641a3dcf 100644 --- a/bridge-proxy/tests/bridge_proxy_blackbox_test.rs +++ b/bridge-proxy/tests/bridge_proxy_blackbox_test.rs @@ -955,17 +955,6 @@ fn bridge_proxy_refund_tx_test() { .check_account(USER_ADDRESS) .esdt_balance(BRIDGE_TOKEN_ID, BigUint::from(INITIAL_BALANCE)); - test.world - .tx() - .from(USER_ADDRESS) - .to(BRIDGE_PROXY_ADDRESS) - .typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy) - .execute_refund_transaction(1u32) - .returns(ExpectError(4, "Refund executed too early!")) - .run(); - - test.set_block_round(DELAY_BEFORE_OWNER_CAN_REFUND_TRANSACTION + 1); - test.world .tx() .from(USER_ADDRESS)