Skip to content

Commit 738ee20

Browse files
silva-fjKailai-Wangfelixfaisal
authored
Fix cross chain swaps (#3407)
Co-authored-by: Kailai-Wang <Kailai.Wang@hotmail.com> Co-authored-by: Faisal Ahmed <42486737+felixfaisal@users.noreply.github.com>
1 parent 5e394bd commit 738ee20

File tree

6 files changed

+85
-59
lines changed

6 files changed

+85
-59
lines changed

tee-worker/omni-executor/ethereum-rpc/src/lib.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,23 @@ impl RpcProvider for AlloyRpcProvider {
9494
.map_err(|e| error!("Could not get transaction count: {:?}", e))
9595
}
9696

97-
async fn send_transaction(&self, tx: Self::Transaction) -> Result<(), ()> {
98-
if self.wallet.is_none() {
97+
async fn send_transaction(&self, raw_tx: Self::Transaction) -> Result<(), ()> {
98+
let Some(ref wallet) = self.wallet else {
99+
error!("Provider without a wallet cannot send transactions");
99100
return Err(());
100-
}
101+
};
101102

102103
let provider = ProviderBuilder::new()
103-
.wallet(
104-
self.wallet
105-
.clone()
106-
.ok_or(error!("Provider without a wallet cannot send transactions"))?,
107-
)
104+
.wallet(wallet.clone())
108105
.on_http(self.url.parse().map_err(|e| error!("Could not parse rpc url: {:?}", e))?);
109106

107+
let signer_address = wallet.default_signer().address();
108+
let mut tx = raw_tx.from(signer_address);
109+
// Bump the gas by 10%
110+
// TODO: Set gas fees via CLI
111+
tx.gas = Some(self.estimate_gas(tx.clone()).await? * 110 / 100);
112+
tx.gas_price = Some(self.get_gas_price().await?);
113+
110114
let pending_tx = provider.send_transaction(tx).await.map_err(|e| {
111115
error!("Could not send transaction: {:?}", e);
112116
})?;

tee-worker/omni-executor/executor-worker/src/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub struct RunArgs {
2121
pub solana_url: String,
2222
pub pumpx_signer_url: String,
2323
pub worker_url: String,
24-
pub bsc_url: Option<String>,
24+
pub bsc_url: String,
2525
pub bsc_testnet_url: Option<String>,
2626
#[arg(long, short = 'b', default_value = "0", help = "Start block to sync from parentchain")]
2727
pub start_block: u64,

tee-worker/omni-executor/executor-worker/src/main.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,7 @@ async fn main() -> Result<(), ()> {
174174

175175
let mut rpc_endpoint_registry = RpcEndpointRegistry::new();
176176
rpc_endpoint_registry.insert(Chain::Solana, args.solana_url.clone());
177-
178-
if let Some(ref bsc_url) = args.bsc_url {
179-
rpc_endpoint_registry.insert(Chain::Ethereum(56), bsc_url.to_owned());
180-
}
177+
rpc_endpoint_registry.insert(Chain::Ethereum(56), args.bsc_url.clone());
181178

182179
if let Some(ref bsc_testnet_url) = args.bsc_testnet_url {
183180
rpc_endpoint_registry.insert(Chain::Ethereum(97), bsc_testnet_url.to_owned());
@@ -202,12 +199,12 @@ async fn main() -> Result<(), ()> {
202199
.expect("Could not create accounting contract signer");
203200
let accounting_contract_wallet = EthereumWallet::from(accounting_contract_signer);
204201

205-
let ethereum_rpc_provider = ethereum_rpc::AlloyRpcProvider::new_with_wallet(
206-
&args.ethereum_url,
202+
let bsc_rpc_provider = ethereum_rpc::AlloyRpcProvider::new_with_wallet(
203+
&args.bsc_url,
207204
accounting_contract_wallet,
208205
);
209206
let accounting_contract_client = AccountingContractClient::new(
210-
ethereum_rpc_provider,
207+
bsc_rpc_provider,
211208
args.accounting_contract_address.parse().unwrap(),
212209
);
213210

tee-worker/omni-executor/intent/executors/cross-chain/src/lib.rs

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use heima_authentication::auth_token::AUTH_TOKEN_ACCESS_TYPE;
4141
use rust_decimal::prelude::*;
4242
use rust_decimal::Decimal;
4343
use solana::{signer::RemoteSigner, SolanaClient};
44+
use std::str::FromStr;
4445
use tokio::{
4546
runtime::Handle,
4647
time::{sleep, Duration},
@@ -437,6 +438,15 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
437438
log::error!("Could not get from_wallet from pumpx-signer: {:?}", e)
438439
})?;
439440

441+
let from_address = match from_chain_type {
442+
ChainType::Evm => pubkey_to_evm_address(&from_wallet_address)?,
443+
ChainType::Solana => pubkey_to_solana_address(&from_wallet_address)?,
444+
_ => {
445+
log::error!("Unsupported {:?} wallet address", from_chain_type);
446+
return Err(());
447+
},
448+
};
449+
440450
let to_wallet_address = self
441451
.pumpx_signer_client
442452
.request_wallet(
@@ -449,11 +459,11 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
449459
log::error!("Could not get to_wallet from pumpx-signer: {:?}", e)
450460
})?;
451461

452-
let from_address = match from_chain_type {
453-
ChainType::Evm => pubkey_to_evm_address(&from_wallet_address)?,
454-
ChainType::Solana => pubkey_to_solana_address(&from_wallet_address)?,
462+
let to_address = match to_chain_type {
463+
ChainType::Evm => pubkey_to_evm_address(&to_wallet_address)?,
464+
ChainType::Solana => pubkey_to_solana_address(&to_wallet_address)?,
455465
_ => {
456-
log::error!("Unsupported {:?} wallet address", from_chain_type);
466+
log::error!("Unsupported {:?} wallet address", to_chain_type);
457467
return Err(());
458468
},
459469
};
@@ -633,6 +643,8 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
633643
}
634644

635645
debug!("Waiting for deposit to be confirmed on Binance...");
646+
debug!("Deposit tx_id: {:?}", tx_id);
647+
debug!("Source address: {:?}", from_address);
636648
let mut deposit_confirmed = false;
637649
let start_time = std::time::Instant::now();
638650
let timeout = Duration::from_secs(300); // 5 minute timeout
@@ -650,13 +662,7 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
650662

651663
// Check if there's a recent successful deposit
652664
for deposit in deposit_history {
653-
let deposit_amount: u64 = match Decimal::from_str(&deposit.amount) {
654-
Ok(deposit_amount) => deposit_amount.to_u64().unwrap_or(0),
655-
Err(_) => {
656-
log::error!("Failed to parse deposit amount");
657-
continue;
658-
},
659-
};
665+
debug!("Deposit: {:?}", deposit);
660666
if deposit.status == 2 || deposit.status == 7 {
661667
// 2 = rejected, 7 = Wrong Deposit
662668
log::error!("Deposit failed with status: {}", deposit.status);
@@ -677,8 +683,7 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
677683
if deposit.status == 1 && // 1 = success
678684
deposit.coin == binance_coin_name &&
679685
deposit.network == binance_network_info.network &&
680-
deposit.source_address == Some(from_address.clone()) &&
681-
deposit_amount == amount_to_transfer
686+
deposit.source_address == Some(from_address.clone())
682687
{
683688
deposit_confirmed = true;
684689
debug!(
@@ -687,6 +692,7 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
687692
);
688693
break;
689694
}
695+
debug!("Deposit not confirmed yet, status: {}", deposit.status);
690696
}
691697

692698
if !deposit_confirmed {
@@ -856,7 +862,9 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
856862

857863
debug!("Total received {} bnb", bnb_received);
858864

859-
let payout_address: Address = Address::from_slice(&to_wallet_address);
865+
let payout_address = Address::from_str(&to_address).map_err(|_| {
866+
log::error!("Failed to parse payout address");
867+
})?;
860868
let payout_amount = match str_to_u256(&bnb_received, 18) {
861869
Some(a) => a,
862870
None => {
@@ -885,6 +893,7 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
885893
)?;
886894

887895
debug!("Received {:?} nonce", user_nonce);
896+
let user_nonce = user_nonce + U256::from(1u64);
888897
debug!("Calling accounting contract payout with address {:?}, nonce {:?} and amount {:?}", payout_address, user_nonce, payout_amount);
889898

890899
self.accounting_contract_client
@@ -895,31 +904,43 @@ impl<Provider: EthereumRpcProvider<Transaction = TransactionRequest> + Send + Sy
895904
})?;
896905

897906
debug!("Calling pumpx get_gas_info, chain_id: {}", pumpx_config.to_chain_id);
898-
let gas_info = self
907+
let res = self
899908
.pumpx_api
900909
.get_gas_info(&access_token, pumpx_config.to_chain_id)
901910
.await
902911
.map_err(|_| {
903912
log::error!("Failed to get gas info");
904913
})?;
905-
debug!("Response get_gas_info: {:?}", gas_info);
914+
debug!("Response get_gas_info: {:?}", res);
906915

907-
let Some(gas_info_data) = gas_info.data else {
916+
let Some(gas_info_data) = res.data else {
908917
log::error!("Response data of call get gas info is none");
909918
return Err(());
910919
};
920+
let Some(gas_info) = gas_info_data
921+
.gas_info
922+
.iter()
923+
.find(|g| g.chain_id == pumpx_config.to_chain_id.to_string())
924+
else {
925+
log::error!(
926+
"Could not find matching gas_info with chain_id {}",
927+
pumpx_config.to_chain_id
928+
);
929+
return Err(());
930+
};
931+
911932
let gas_fee = match pumpx_config.gas_type {
912-
1 => gas_info_data.gas_info.normal,
913-
2 => gas_info_data.gas_info.fast,
914-
3 => gas_info_data.gas_info.super_fast,
933+
1 => &gas_info.normal,
934+
2 => &gas_info.fast,
935+
3 => &gas_info.super_fast,
915936
_ => {
916937
log::error!("Unsupported gas type: {}", pumpx_config.gas_type);
917938
return Err(());
918939
},
919940
};
920941
debug!("Gas fee for chain_id {} is {}", pumpx_config.to_chain_id, gas_fee);
921942

922-
let amount_in = match calculate_amount_in(&bnb_received, &gas_fee) {
943+
let amount_in = match calculate_amount_in(&bnb_received, gas_fee) {
923944
Some(a) => a,
924945
None => {
925946
log::error!(

tee-worker/omni-executor/pumpx/src/pumpx_api/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ pub struct GetGasInfoParams {
318318
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
319319
#[serde(rename_all = "camelCase")]
320320
pub struct GetGasInfoResponseData {
321-
pub gas_info: GasInfo,
321+
pub gas_info: Vec<GasInfo>,
322322
}
323323

324324
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]

tee-worker/omni-executor/solana/src/signer.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ impl RemoteSigner {
2828

2929
impl Signer for RemoteSigner {
3030
fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
31-
let wallet = self.handle.block_on(async {
32-
self.signer_client
33-
.request_wallet(ChainType::Solana, self.wallet_index, self.omni_account)
34-
.await
35-
.map_err(|e| {
36-
log::error!("Error requesting wallet: {:?}", e);
37-
SignerError::Custom(format!("Error requesting wallet: {:?}", e))
38-
})
31+
let wallet = tokio::task::block_in_place(|| {
32+
self.handle.block_on(async {
33+
self.signer_client
34+
.request_wallet(ChainType::Solana, self.wallet_index, self.omni_account)
35+
.await
36+
.map_err(|e| {
37+
log::error!("Error requesting wallet: {:?}", e);
38+
SignerError::Custom(format!("Error requesting wallet: {:?}", e))
39+
})
40+
})
3941
})?;
4042
let wallet_pubkey: [u8; 32] = wallet.try_into().map_err(|e| {
4143
log::error!("Error converting wallet to Pubkey: {:?}", e);
@@ -46,19 +48,21 @@ impl Signer for RemoteSigner {
4648
}
4749

4850
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
49-
let signed_message = self.handle.block_on(async {
50-
self.signer_client
51-
.request_signature(
52-
ChainType::Solana,
53-
self.wallet_index,
54-
self.omni_account,
55-
message.to_vec(),
56-
)
57-
.await
58-
.map_err(|e| {
59-
log::error!("Error requesting signature: {:?}", e);
60-
SignerError::Custom(format!("Error requesting signature: {:?}", e))
61-
})
51+
let signed_message = tokio::task::block_in_place(|| {
52+
self.handle.block_on(async {
53+
self.signer_client
54+
.request_signature(
55+
ChainType::Solana,
56+
self.wallet_index,
57+
self.omni_account,
58+
message.to_vec(),
59+
)
60+
.await
61+
.map_err(|e| {
62+
log::error!("Error requesting signature: {:?}", e);
63+
SignerError::Custom(format!("Error requesting signature: {:?}", e))
64+
})
65+
})
6266
})?;
6367
let signed_message: [u8; 64] = signed_message.try_into().map_err(|e| {
6468
log::error!("Error converting signed message to Signature: {:?}", e);

0 commit comments

Comments
 (0)