How to send ERC20?

I cam across the example for basic_ethereum I want to extend it and implement ERC20 transfer and so write this code:

const USDC_ADDRESS: &str = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238";

#[update]
pub async fn send_usdc(to: String, amount: Nat) -> String {
    let caller = validate_caller_not_anonymous();
    let to_address = Address::from_str(&to).unwrap_or_else(|e| {
        ic_cdk::trap(&format!("failed to parse the recipient address: {:?}", e))
    });

    let usdc_contract_address = Address::from_str(USDC_ADDRESS).expect("Invalid USDC address");
    let usdc_contract_address_alloy = alloy_primitives::Address::from_slice(&usdc_contract_address.as_ref());
    
    let amount_u256 = nat_to_u256(amount);
    let transfer_data = format!(
        "0xa9059cbb{}{}",
        hex::encode(to_address.as_ref()), // recipient address
        hex::encode(&amount_u256.to_be_bytes::<32>()) // specify 32 bytes for U256
    );    

    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();

    let transaction = TxEip1559 {
        chain_id,
        nonce,
        gas_limit,
        max_fee_per_gas,
        max_priority_fee_per_gas,
        to: TxKind::Call(usdc_contract_address_alloy),
        value: U256::from(0), // No ETH is sent, only USDC
        access_list: Default::default(),
        input: transfer_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("BUG: 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
    );

    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()
}

But the transactions are not success, they are failing, what could I do to correct it?