Skip to content

Commit

Permalink
Merge pull request #255 from multiversx/v3.5-audit-fixes
Browse files Browse the repository at this point in the history
V3.1 audit fixes
  • Loading branch information
iulianpascalau authored Dec 19, 2024
2 parents 7eb68ea + fdcecd4 commit 67f7f6b
Show file tree
Hide file tree
Showing 46 changed files with 1,316 additions and 1,508 deletions.
71 changes: 44 additions & 27 deletions bridge-proxy/src/bridge-proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
use multiversx_sc::imports::*;

pub mod config;
mod events;

use sc_proxies::bridged_tokens_wrapper_proxy;
use sc_proxies::esdt_safe_proxy;
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 DEFAULT_GAS_LIMIT_FOR_REFUND_CALLBACK: u64 = 1_000_000; // 1 million

#[multiversx_sc::contract]
pub trait BridgeProxyContract:
config::ConfigModule
+ events::EventsModule
+ multiversx_sc_modules::pause::PauseModule
+ storage_module::CommonStorageModule
{
Expand Down Expand Up @@ -103,39 +104,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.refund_transaction(tx_id);
self.add_pending_tx_to_refund(tx_id);
self.execute_generated_refund(tx_id);
} else {
self.execute_succesfully_finished(tx_id);
}
self.cleanup_transaction(tx_id);
self.pending_transactions().remove(&tx_id);
}

fn refund_transaction(&self, tx_id: usize) {
let tx = self.get_pending_transaction_by_id(tx_id);
#[endpoint(executeRefundTransaction)]
fn execute_refund_transaction(&self, tx_id: usize) {
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)
.create_transaction(
.create_refund_transaction(
tx.from,
OptionalValue::Some(esdt_safe_proxy::RefundInfo {
address: tx.to,
Expand All @@ -149,6 +139,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 {
Expand Down Expand Up @@ -184,13 +176,20 @@ pub trait BridgeProxyContract:
}

fn finish_execute_gracefully(&self, tx_id: usize) {
self.refund_transaction(tx_id);
self.cleanup_transaction(tx_id);
self.add_pending_tx_to_refund(tx_id);
self.pending_transactions().remove(&tx_id);
}

fn cleanup_transaction(&self, tx_id: usize) {
self.pending_transactions().remove(&tx_id);
fn finish_refund(&self, tx_id: usize) {
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) {
let tx = self.get_pending_transaction_by_id(tx_id);
self.refund_transactions().insert(tx_id, tx);
}

fn get_next_tx_id(&self) -> usize {
Expand All @@ -217,4 +216,22 @@ pub trait BridgeProxyContract:
}
transactions
}

#[view(getRefundTransactionById)]
fn get_refund_transaction_by_id(&self, tx_id: usize) -> EthTransaction<Self::Api> {
let tx = self.refund_transactions().get(&tx_id);
require!(tx.is_some(), "Invalid tx id");
tx.unwrap()
}

#[view(getRefundTransactions)]
fn get_refund_transactions(
&self,
) -> MultiValueEncoded<MultiValue2<usize, EthTransaction<Self::Api>>> {
let mut transactions = MultiValueEncoded::new();
for (tx_id, tx) in self.refund_transactions().iter() {
transactions.push(MultiValue2((tx_id, tx)));
}
transactions
}
}
10 changes: 7 additions & 3 deletions bridge-proxy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ use transaction::EthTransaction;

#[multiversx_sc::module]
pub trait ConfigModule {
#[storage_mapper("pending_transactions")]
#[storage_mapper("pendingTransactions")]
fn pending_transactions(&self) -> MapMapper<usize, EthTransaction<Self::Api>>;

#[view(refundTransactions)]
#[storage_mapper("refundTransactions")]
fn refund_transactions(&self) -> MapMapper<usize, EthTransaction<Self::Api>>;

#[storage_mapper("payments")]
fn payments(&self, tx_id: usize) -> SingleValueMapper<EsdtTokenPayment<Self::Api>>;

#[storage_mapper("batch_id")]
#[storage_mapper("batchId")]
fn batch_id(&self, tx_id: usize) -> SingleValueMapper<u64>;

#[view(highestTxId)]
#[storage_mapper("highest_tx_id")]
#[storage_mapper("highestTxId")]
fn highest_tx_id(&self) -> SingleValueMapper<usize>;

#[storage_mapper("ongoingExecution")]
Expand Down
8 changes: 8 additions & 0 deletions bridge-proxy/src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[multiversx_sc::module]
pub trait EventsModule {
#[event("executeSuccesfullyFinished")]
fn execute_succesfully_finished(&self, #[indexed] tx_id: usize);

#[event("executeGeneratedRefund")]
fn execute_generated_refund(&self, #[indexed] tx_id: usize);
}
Loading

0 comments on commit 67f7f6b

Please sign in to comment.