I’m trying to implement Uniswap v3 with Rust. The transaction seems to be processed, but I’m seeing an error on Etherscan: “Warning! Error encountered during contract execution [execution reverted]”.
Etherscan Transaction: Sepolia Transaction Hash (Txhash) Details | Etherscan
Here’s my Rust code for the swap:
const UNISWAP_ROUTER_ADDRESS: &str = "0xeE567Fe1712Faf6149d80dA1E6934E354124CfE3";
const USDC_ADDRESS: &str = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238";
#[update]
pub async fn swap_eth_to_usdc() -> String {
let caller = validate_caller_not_anonymous();
let usdc_address = Address::from_str(USDC_ADDRESS).expect("Invalid USDC address");
let router_address = Address::from_str(UNISWAP_ROUTER_ADDRESS).expect("Invalid router address");
let router_alloy_address: AlloyAddress = AlloyAddress::from_slice(router_address.as_ref());
// ETH to swap in Wei and minimum USDC to receive
let eth_amount = U256::from(5 * 10_u128.pow(16)); // 0.05 ETH
let min_usdc = U256::from(1 * 10_u128.pow(6)); // Minimum 1 USDC with 6 decimals
let chain_id = read_state(|s| s.ethereum_network().chain_id());
let nonce = nat_to_u64(transaction_count(Some(caller), Some(BlockTag::Latest)).await);
let (gas_limit, max_fee_per_gas, max_priority_fee_per_gas) = estimate_transaction_fees();
// Data payload for Uniswap's `swapExactETHForTokens` function
let swap_data = format!(
// "0x7ff36ab500000000000000000000000000000000000000000000000000000000000000000000000000000000000000{}000000000000000000000000{}",
"0xb6f9de95{}{}",
hex::encode(usdc_address.as_ref()),
hex::encode(router_alloy_address.as_ref() as &[u8; 20]) // Explicitly cast to &[u8; 20]
);
// Create and sign transaction
let transaction = TxEip1559 {
chain_id,
nonce,
gas_limit,
max_fee_per_gas,
max_priority_fee_per_gas,
to: TxKind::Call(router_alloy_address),
value: eth_amount,
access_list: Default::default(),
input: swap_data.into(),
};
let wallet = EthereumWallet::new(caller).await;
let tx_hash = transaction.signature_hash().0;
let (raw_signature, recovery_id) = wallet.sign_with_ecdsa(tx_hash).await;
let signature = Signature::from_bytes_and_parity(&raw_signature, recovery_id.is_y_odd())
.expect("Failed to create a signature");
let signed_tx = transaction.into_signed(signature);
let raw_transaction_hash = *signed_tx.hash();
let mut tx_bytes: Vec<u8> = vec![];
TxEnvelope::from(signed_tx).encode_2718(&mut tx_bytes);
let raw_transaction_hex = format!("0x{}", hex::encode(&tx_bytes));
ic_cdk::println!(
"Sending raw transaction hex {} with transaction hash {}",
raw_transaction_hex,
raw_transaction_hash
);
// Send transaction
let single_rpc_service = read_state(|s| s.single_evm_rpc_service());
let (result,) = EVM_RPC
.eth_send_raw_transaction(
single_rpc_service,
None,
raw_transaction_hex.clone(),
2_000_000_000_u128,
)
.await
.unwrap_or_else(|e| {
panic!(
"Failed to send raw transaction {}, error: {:?}",
raw_transaction_hex, e
)
});
ic_cdk::println!(
"Result of sending raw transaction {}: {:?}",
raw_transaction_hex,
result
);
raw_transaction_hash.to_string()
}