Skip to content

Commit

Permalink
Fix the attached amount in jetton transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
pashinov committed Dec 19, 2024
1 parent 961c7a3 commit eea908a
Showing 1 changed file with 8 additions and 92 deletions.
100 changes: 8 additions & 92 deletions src/core/jetton_wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,99 +109,15 @@ impl JettonWallet {

pub async fn estimate_min_attached_amount(
&self,
amount: BigUint,
destination: MsgAddressInt,
remaining_gas_to: MsgAddressInt,
custom_payload: Option<ton_types::Cell>,
callback_value: BigUint,
callback_payload: Option<ton_types::Cell>,
_amount: BigUint,
_destination: MsgAddressInt,
_remaining_gas_to: MsgAddressInt,
_custom_payload: Option<ton_types::Cell>,
_callback_value: BigUint,
_callback_payload: Option<ton_types::Cell>,
) -> Result<u64> {
const FEE_MULTIPLIER: u128 = 2;

// Prepare internal message
let internal_message = self.prepare_transfer(
amount,
destination,
remaining_gas_to,
custom_payload,
callback_value,
callback_payload,
0,
)?;

let mut message = ton_block::Message::with_int_header(ton_block::InternalMessageHeader {
src: ton_block::MsgAddressIntOrNone::Some(
internal_message
.source
.unwrap_or_else(|| self.owner.clone()),
),
dst: internal_message.destination,
..Default::default()
});

message.set_body(internal_message.body.clone());

// Prepare executor
let transport = self.contract_subscription.transport().clone();
let config = transport
.get_blockchain_config(self.clock.as_ref(), true)
.await?;

let mut tree = TransactionsTreeStream::new(message, config, transport, self.clock.clone());
tree.unlimited_account_balance();
tree.unlimited_message_balance();

type Err = fn(Option<i32>) -> JettonWalletError;
let check_exit_code = |tx: &ton_block::Transaction, err: Err| -> Result<()> {
let descr = tx.read_description()?;
if descr.is_aborted() {
let exit_code = match descr {
ton_block::TransactionDescr::Ordinary(descr) => match descr.compute_ph {
ton_block::TrComputePhase::Vm(phase) => Some(phase.exit_code),
ton_block::TrComputePhase::Skipped(_) => None,
},
_ => None,
};
Err(err(exit_code).into())
} else {
Ok(())
}
};

let mut attached_amount: u128 = 0;

// Simulate source transaction
let source_tx = tree.next().await?.ok_or(JettonWalletError::NoSourceTx)?;
check_exit_code(&source_tx, JettonWalletError::SourceTxFailed)?;
attached_amount += source_tx.total_fees.grams.as_u128();

if source_tx.outmsg_cnt == 0 {
return Err(JettonWalletError::NoDestTx.into());
}

if let Some(message) = tree.peek() {
if message.state_init().is_some() && message.src_ref() == Some(self.address()) {
// Simulate first deploy transaction
// NOTE: we don't need to count attached amount here because of separate `initial_balance`
let _ = tree.next().await?.ok_or(JettonWalletError::NoDestTx)?;
//also we ignore non zero exit code for deploy transactions
}
}

tree.retain_message_queue(|message| {
message.state_init().is_none() && message.src_ref() == Some(self.address())
});

if tree.message_queue().len() != 1 {
return Err(JettonWalletError::NoDestTx.into());
}

// Simulate destination transaction
let dest_tx = tree.next().await?.ok_or(JettonWalletError::NoDestTx)?;
check_exit_code(&dest_tx, JettonWalletError::DestinationTxFailed)?;
attached_amount += dest_tx.total_fees.grams.as_u128();

Ok((attached_amount * FEE_MULTIPLIER) as u64)
const ATTACHED_AMOUNT: u64 = 50_000_000; // 0.05 TON
Ok(ATTACHED_AMOUNT)
}

pub fn prepare_transfer(
Expand Down

0 comments on commit eea908a

Please sign in to comment.