126 lines
4.2 KiB
Rust
126 lines
4.2 KiB
Rust
pub mod helpers;
|
|
pub mod mint;
|
|
pub mod receipt;
|
|
pub mod block_scanner;
|
|
pub mod mempool;
|
|
|
|
use clap::Parser;
|
|
use std::sync::Arc;
|
|
|
|
use ethers::prelude::{k256::ecdsa::SigningKey, *};
|
|
|
|
use crate::mint::Mint;
|
|
use crate::mempool::loop_mempool;
|
|
use crate::block_scanner::loop_blocks;
|
|
use crate::helpers::{setup_signer, user_balance, wei_to_float, wei_to_gwei};
|
|
|
|
use colored::*;
|
|
|
|
#[macro_export]
|
|
macro_rules! timestamp_print {
|
|
($color: expr, $message: expr) => {
|
|
println!(
|
|
"{} {} {}",
|
|
chrono::Local::now()
|
|
.format("[%Y-%m-%d]")
|
|
.to_string()
|
|
.color($color),
|
|
chrono::Local::now()
|
|
.format("[%H:%M:%S]")
|
|
.to_string()
|
|
.color($color),
|
|
$message.color($color)
|
|
);
|
|
};
|
|
}
|
|
|
|
pub struct Config {
|
|
#[allow(dead_code)]
|
|
pub http: Arc<SignerMiddleware<Provider<Http>, Wallet<SigningKey>>>,
|
|
#[allow(dead_code)]
|
|
pub wss: Arc<Provider<Ws>>,
|
|
}
|
|
|
|
impl Config {
|
|
pub async fn new() -> Self {
|
|
let network = std::env::var("NETWORK_RPC").expect("NETWORK_RPC missing");
|
|
let provider = Provider::<Http>::try_from(network).unwrap();
|
|
let middleware = Arc::new(setup_signer(provider.clone()).await);
|
|
|
|
let ws_network = std::env::var("NETWORK_WSS").expect("NETWORK_WS missing");
|
|
let ws_provider = Provider::<Ws>::connect(ws_network).await.unwrap();
|
|
|
|
Self {
|
|
http: middleware,
|
|
wss: Arc::new(ws_provider),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn run() {
|
|
let config = Arc::new(Config::new().await);
|
|
let mint = Mint::parse();
|
|
mint.check_requirements(config.clone()).await.unwrap();
|
|
|
|
let config_clone = config.clone();
|
|
|
|
if mint.backrun {
|
|
let handle_blocks = tokio::spawn(async move {
|
|
loop_blocks(config_clone.http.clone()).await;
|
|
});
|
|
let owner_tx = Arc::new(
|
|
loop_mempool(
|
|
config.wss.clone(),
|
|
mint.contract)
|
|
.await
|
|
.unwrap());
|
|
let config_clone = config.clone();
|
|
|
|
let last_block_price = config.http.get_gas_price().await.unwrap();
|
|
let sniper_gas_price = last_block_price.as_u64() * 125 / 100;
|
|
|
|
let handle = tokio::spawn(async move {
|
|
let sniping_receipt = mint.sniping(
|
|
config_clone,
|
|
U256::from(sniper_gas_price),
|
|
).await.unwrap();
|
|
sniping_receipt
|
|
});
|
|
|
|
timestamp_print!(Color::Green, format!("Owner's tx detected: {:#?}", owner_tx.hash));
|
|
timestamp_print!(Color::Blue, format!("Last block gas price: {} Gwei", wei_to_gwei(last_block_price.as_u64())));
|
|
timestamp_print!(Color::Blue, format!("Setting Sniping gas price to: {} Gwei", wei_to_gwei(sniper_gas_price)));
|
|
timestamp_print!(Color::Blue, "SNIPIIIIIIIIING.".to_string());
|
|
timestamp_print!(Color::White, "Waiting for tx to be mined...".to_string());
|
|
|
|
let tx_receipt = handle.await.unwrap();
|
|
|
|
handle_blocks.abort();
|
|
|
|
let mint_receipt = receipt::Transaction::new(tx_receipt);
|
|
let owner_tx_position = config.http.get_transaction_receipt(owner_tx.hash).await.unwrap().unwrap().transaction_index;
|
|
timestamp_print!(Color::Blue, format!("Owner's tx position in block: {}", owner_tx_position));
|
|
mint_receipt.print();
|
|
|
|
} else {
|
|
mint.trigger_timestamp().unwrap();
|
|
let last_block_price = config.http.get_gas_price().await.unwrap();
|
|
let sniper_gas_price = last_block_price.as_u64() * 125 / 100;
|
|
let handle = tokio::spawn(async move {
|
|
let sniping_receipt = mint.sniping(
|
|
config_clone,
|
|
U256::from(sniper_gas_price),
|
|
).await.unwrap();
|
|
sniping_receipt
|
|
});
|
|
timestamp_print!(Color::Blue, "SNIPIIIIIIIIING.".to_string());
|
|
timestamp_print!(Color::White, "Waiting for tx to be mined...".to_string());
|
|
let tx_receipt = handle.await.unwrap();
|
|
let mint_receipt = receipt::Transaction::new(tx_receipt);
|
|
mint_receipt.print();
|
|
|
|
}
|
|
|
|
let balance = user_balance(config.http.clone()).await.unwrap();
|
|
timestamp_print!(Color::White, format!("Balance after mint: {} ETH", wei_to_float(balance.as_u64())));
|
|
} |