Skip to content

Commit

Permalink
Merge pull request #236 from multiversx/merge-v3-into-v3.5-18.10.2024
Browse files Browse the repository at this point in the history
Merge v3 into v3.5 18.10.2024
  • Loading branch information
evelinemolnar authored Oct 21, 2024
2 parents 4bfa1b5 + ff3cdb2 commit 6a0d1cc
Show file tree
Hide file tree
Showing 45 changed files with 1,137 additions and 446 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ permissions:
jobs:
contracts:
name: Contracts
uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.2.0
uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.3.1
with:
rust-toolchain: stable
secrets:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ permissions:

jobs:
build:
uses: multiversx/mx-sc-actions/.github/workflows/reproducible-build.yml@v3.2.0
uses: multiversx/mx-sc-actions/.github/workflows/reproducible-build.yml@v3.3.1
with:
image_tag: v7.0.0
image_tag: v8.0.1
attach_to_existing_release: true
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@
],
"function": "deposit",
"arguments": [
"0x30313032303330343035303630373038303931300000000000000000050063726f7766756e64696e675f5f5f5f5f5f5f5f5f5f5f0000000d4252494447452d3132333435360000000201f4000000000000000101000000150000000466756e6400000000009896800100000000"
"0x30313032303330343035303630373038303931300000000000000000050063726f7766756e64696e675f5f5f5f5f5f5f5f5f5f5f0000000d4252494447452d3132333435360000000201f4000000000000000101000000150000000466756e6400000000009896800100000000",
"0x01"
],
"gasLimit": "5,000,000"
},
Expand Down Expand Up @@ -226,7 +227,7 @@
"arguments": [
"0x01"
],
"gasLimit": "5,000,000"
"gasLimit": "200000000"
},
"expect": {
"out": [],
Expand Down
76 changes: 65 additions & 11 deletions bridge-proxy/src/bridge-proxy.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#![no_std]
use multiversx_sc::imports::*;
use multiversx_sc_modules::ongoing_operation::*;

pub mod config;

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 MIN_GAS_TO_SAVE_PROGRESS: u64 = 100_000;

#[multiversx_sc::contract]
pub trait BridgeProxyContract:
config::ConfigModule + multiversx_sc_modules::pause::PauseModule
config::ConfigModule
+ multiversx_sc_modules::pause::PauseModule
+ multiversx_sc_modules::ongoing_operation::OngoingOperationModule
{
#[init]
fn init(&self, opt_multi_transfer_address: OptionalValue<ManagedAddress>) {
Expand All @@ -27,7 +33,7 @@ pub trait BridgeProxyContract:

#[payable("*")]
#[endpoint]
fn deposit(&self, eth_tx: EthTransaction<Self::Api>) {
fn deposit(&self, eth_tx: EthTransaction<Self::Api>, batch_id: u64) {
self.require_not_paused();
let caller = self.blockchain().get_caller();
let payment = self.call_value().single_esdt();
Expand All @@ -37,6 +43,7 @@ pub trait BridgeProxyContract:
);
let tx_id = self.pending_transactions().push(&eth_tx);
self.payments(tx_id).set(&payment);
self.batch_id(tx_id).set(batch_id);
}

#[endpoint(execute)]
Expand Down Expand Up @@ -65,13 +72,16 @@ pub trait BridgeProxyContract:
};

if call_data.endpoint.is_empty()
|| call_data.gas_limit == 0
|| call_data.gas_limit < MIN_GAS_LIMIT_FOR_SC_CALL
|| call_data.gas_limit > MAX_GAS_LIMIT_FOR_SC_CALL
{
self.finish_execute_gracefully(tx_id);
return;
}

let gas_left = self.blockchain().get_gas_left();
require!(gas_left > call_data.gas_limit + DEFAULT_GAS_LIMIT_FOR_REFUND_CALLBACK, "Not enough gas to execute");

let tx_call = self
.tx()
.to(&tx.to)
Expand All @@ -93,7 +103,8 @@ pub trait BridgeProxyContract:
tx_call.register_promise();
}

#[endpoint(cancel)]
// 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();
Expand All @@ -117,19 +128,51 @@ pub trait BridgeProxyContract:

fn refund_transaction(&self, tx_id: usize) {
let tx = self.get_pending_transaction_by_id(tx_id);
let payment = self.payments(tx_id).get();
let esdt_safe_addr = self.bridged_tokens_wrapper_address().get();
let esdt_safe_contract_address = self.esdt_safe_contract_address().get();

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_addr)
.typed(bridged_tokens_wrapper_proxy::BridgedTokensWrapperProxy)
.unwrap_token_create_transaction(&tx.token_id, tx.from, OptionalValue::Some(tx.to))
.to(esdt_safe_contract_address)
.typed(esdt_safe_proxy::EsdtSafeProxy)
.create_transaction(tx.from, OptionalValue::Some(esdt_safe_proxy::RefundInfo {
address: tx.to,
initial_batch_id: batch_id,
initial_nonce: tx.tx_nonce,
}))
.single_esdt(
&unwrapped_token.token_identifier,
unwrapped_token.token_nonce,
&unwrapped_token.amount,
)
.sync_call();
}

fn unwrap_token(&self, requested_token: &TokenIdentifier, tx_id: usize) -> EsdtTokenPayment {
let payment = self.payments(tx_id).get();
let bridged_tokens_wrapper_address = self.bridged_tokens_wrapper_address().get();

let transfers = self
.tx()
.to(bridged_tokens_wrapper_address) .typed(bridged_tokens_wrapper_proxy::BridgedTokensWrapperProxy)
.unwrap_token(requested_token)
.single_esdt(
&payment.token_identifier,
payment.token_nonce,
&payment.amount,
)
.returns(ReturnsBackTransfers)
.sync_call();

require!(
transfers.total_egld_amount == 0,
"Expected only one esdt payment"
);
require!(
transfers.esdt_payments.len() == 1,
"Expected only one esdt payment"
);
transfers.esdt_payments.get(0)
}

fn finish_execute_gracefully(&self, tx_id: usize) {
Expand All @@ -143,17 +186,28 @@ pub trait BridgeProxyContract:
self.ongoing_execution(tx_id).clear();
}

#[endpoint(updateLowestTxId)]
fn update_lowest_tx_id(&self) {
let mut new_lowest = self.lowest_tx_id().get();
let len = self.pending_transactions().len();

while new_lowest < len && self.pending_transactions().item_is_empty(new_lowest) {
self.run_while_it_has_gas(MIN_GAS_TO_SAVE_PROGRESS, || {
if !self.empty_element(new_lowest, len) {
return STOP_OP;
}

new_lowest += 1;
}

CONTINUE_OP
});

self.lowest_tx_id().set(new_lowest);
}

fn empty_element(&self, current_index: usize, len: usize) -> bool {
current_index < len && self.pending_transactions().item_is_empty(current_index)
}

#[view(getPendingTransactionById)]
fn get_pending_transaction_by_id(&self, tx_id: usize) -> EthTransaction<Self::Api> {
self.pending_transactions()
Expand Down
3 changes: 3 additions & 0 deletions bridge-proxy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ pub trait ConfigModule {
#[storage_mapper("payments")]
fn payments(&self, tx_id: usize) -> SingleValueMapper<EsdtTokenPayment<Self::Api>>;

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

#[view(lowestTxId)]
#[storage_mapper("lowest_tx_id")]
fn lowest_tx_id(&self) -> SingleValueMapper<usize>;
Expand Down
13 changes: 9 additions & 4 deletions bridge-proxy/tests/bridge_proxy_blackbox_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ fn bridge_proxy_execute_crowdfunding_test() {
.from(MULTI_TRANSFER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.deposit(&eth_tx)
.deposit(&eth_tx, 1u64)
.egld_or_single_esdt(
&EgldOrEsdtTokenIdentifier::esdt(BRIDGE_TOKEN_ID),
0,
Expand All @@ -292,6 +292,7 @@ fn bridge_proxy_execute_crowdfunding_test() {
.tx()
.from(OWNER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.gas(200_000_000)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.execute(1u32)
.run();
Expand Down Expand Up @@ -352,7 +353,7 @@ fn multiple_deposit_test() {
.from(MULTI_TRANSFER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.deposit(&eth_tx1)
.deposit(&eth_tx1, 1u64)
.single_esdt(
&TokenIdentifier::from(BRIDGE_TOKEN_ID),
0u64,
Expand All @@ -365,7 +366,7 @@ fn multiple_deposit_test() {
.from(MULTI_TRANSFER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.deposit(&eth_tx2)
.deposit(&eth_tx2, 1u64)
.single_esdt(
&TokenIdentifier::from(BRIDGE_TOKEN_ID),
0u64,
Expand All @@ -385,6 +386,7 @@ fn multiple_deposit_test() {
.tx()
.from(OWNER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.gas(200_000_000)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.execute(1u32)
.run();
Expand All @@ -401,6 +403,7 @@ fn multiple_deposit_test() {
.tx()
.from(OWNER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.gas(200_000_000)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.execute(2u32)
.run();
Expand Down Expand Up @@ -462,7 +465,7 @@ fn test_lowest_tx_id() {
.from(MULTI_TRANSFER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.deposit(tx)
.deposit(tx, 1u64)
.single_esdt(
&TokenIdentifier::from(BRIDGE_TOKEN_ID),
0u64,
Expand All @@ -486,6 +489,7 @@ fn test_lowest_tx_id() {
.tx()
.from(OWNER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.gas(200_000_000)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.execute(i)
.run();
Expand All @@ -506,6 +510,7 @@ fn test_lowest_tx_id() {
.tx()
.from(OWNER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.gas(200_000_000)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.execute(i)
.run();
Expand Down
2 changes: 1 addition & 1 deletion bridge-proxy/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ multiversx_sc_wasm_adapter::endpoints! {
upgrade => upgrade
deposit => deposit
execute => execute
cancel => cancel
updateLowestTxId => update_lowest_tx_id
getPendingTransactionById => get_pending_transaction_by_id
getPendingTransactions => get_pending_transactions
setMultiTransferAddress => set_multi_transfer_contract_address
Expand Down
37 changes: 5 additions & 32 deletions bridged-tokens-wrapper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ pub trait BridgedTokensWrapper:
&self,
requested_token: TokenIdentifier,
to: EthAddress<Self::Api>,
opt_refunding_address: OptionalValue<ManagedAddress>,
) {
let (payment_token, payment_amount) = self.call_value().single_fungible_esdt();
let universal_token_id = self
Expand All @@ -261,21 +260,14 @@ pub trait BridgedTokensWrapper:
};

let caller = self.blockchain().get_caller();
let refunding_addr = match opt_refunding_address {
OptionalValue::Some(refunding_addr) => {
require!(
caller == self.bridge_proxy_contract_address().get(),
"Wrong caller for a refund tx"
);
refunding_addr
}
OptionalValue::None => caller,
};

self.tx()
.to(self.esdt_safe_contract_address().get())
.typed(esdt_safe_proxy::EsdtSafeProxy)
.create_transaction(to, OptionalValue::Some(refunding_addr))
.create_transaction(to, OptionalValue::Some(esdt_safe_proxy::RefundInfo {
address: caller,
initial_batch_id: 0,
initial_nonce: 0,
}))
.single_esdt(&requested_token, 0, &converted_amount)
.sync_call();
}
Expand Down Expand Up @@ -327,22 +319,6 @@ pub trait BridgedTokensWrapper:
}
}

#[only_owner]
#[endpoint(setBridgeProxyContractAddress)]
fn set_bridge_proxy_contract_address(&self, opt_new_address: OptionalValue<ManagedAddress>) {
match opt_new_address {
OptionalValue::Some(sc_addr) => {
require!(
self.blockchain().is_smart_contract(&sc_addr),
"Invalid bridge proxy contract address"
);

self.bridge_proxy_contract_address().set(&sc_addr);
}
OptionalValue::None => self.bridge_proxy_contract_address().clear(),
}
}

#[view(getUniversalBridgedTokenIds)]
#[storage_mapper("universalBridgedTokenIds")]
fn universal_bridged_token_ids(&self) -> UnorderedSetMapper<TokenIdentifier>;
Expand Down Expand Up @@ -372,7 +348,4 @@ pub trait BridgedTokensWrapper:
#[storage_mapper("esdtSafeContractAddress")]
fn esdt_safe_contract_address(&self) -> SingleValueMapper<ManagedAddress>;

#[view(getBridgeProxyContractAddress)]
#[storage_mapper("bridgeProxyContractAddress")]
fn bridge_proxy_contract_address(&self) -> SingleValueMapper<ManagedAddress>;
}
Loading

0 comments on commit 6a0d1cc

Please sign in to comment.