simulate::make_sandwich::test::sandv2_kyber_swap' panicked at 'called `Result::unwrap()` on an `Err` value: InternalError(Http(Response { status: 200, version: HTTP/1.1, headers: {"date": "Tue, 18 Jul 2023 15:04:03 GMT", "content-length": "0"}, body: Some([]) }))', src/utils/testhelper.rs:39:55
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'simulate::make_sandwich::test::sandv2_multi_with_three_expect_one_reverts' panicked at 'called `Result::unwrap()` on an `Err` value: InternalError(Http(Response { status: 200, version: HTTP/1.1, headers: {"date": "Tue, 18 Jul 2023 15:04:03 GMT", "content-length": "0"}, body: Some([]) }))', src/utils/testhelper.rs:39:55
RPC_URL_WSS=wss://eth-mainnet.g.alchemy.com/v2/wE6H0DZdOWaVWL2RIRsq8eEjC6KWVD74
SEARCHER_PRIVATE_KEY=mykey
FLASHBOTS_AUTH_KEY=mykey
SANDWICH_CONTRACT=0x8dCE61A5701165D05af240Ee0cbDEc9042964A01
INTERVAL_BLOCK_NEW_POOL=50
V2_ALERT_DISCORD_WEBHOOK=https://discord.com/api/webhooks/1130844464777269289/nwy6w_7PzKj5CIWVxf6UQ-Q6PSBVFHl6_1GPbKKq2LoPxHRHWKH_p5bvd5dg71G2ltOR
V3_ALERT_DISCORD_WEBHOOK=https://discord.com/api/webhooks/1130844476177399918/2XvSYs_w0tZHcpyCC0lzFMJ7HJQytT7j8ntHt0OSP00hBxddPkWJoJLqsUbimQRnYQeP
POISON_ALERT_DISCORD_WEBHOOK=https://discord.com/api/webhooks/1130845040336457778/rRxV_OzqKi3b2Gp7_QVlKbytcOc6eJJE7GUmmZKiupbeOCcMm47ZHy--tvcPrrdouOVF
SANDWICH_INCEPTION_BLOCK=17720362
use std::{sync::Arc, time::Duration};
use ethers::{
prelude::*,
utils::{Anvil, AnvilInstance},
};
use crate::{
prelude::{Erc20, Pool, PoolVariant, UniswapV3Pool},
types::BlockInfo,
};
use super::{constants::get_weth_address, dotenv::get_sandwich_contract_address};
pub async fn get_next_block_info(prev_block_number: u64, client: &Arc<Provider<Ws>>) -> BlockInfo {
let prev_block = client.get_block(prev_block_number).await.unwrap().unwrap();
BlockInfo::find_next_block_info(prev_block)
}
// need to return anvil instance to keep it alive (so that we can make calls)
pub async fn create_fork_ws(fork_block_num: u64) -> (Arc<Provider<Ws>>, AnvilInstance) {
let port_num: u16 = rand::Rng::gen_range(&mut rand::thread_rng(), 3000..4000);
let _anvil = Anvil::new()
.fork(format!(
"https://eth-mainnet.g.alchemy.com/v2/wE6H0DZdOWaVWL2RIRsq8eEjC6KWVD74@{}",
fork_block_num
))
.port(port_num)
.spawn();
let ws_fork = Ws::connect(format!("ws://127.0.0.1:{}", port_num))
.await
.unwrap();
let ws_provider_fork = Provider::new(ws_fork).interval(Duration::from_millis(100));
(Arc::new(ws_provider_fork), _anvil)
}
pub async fn create_ws() -> Arc<Provider<Ws>> {
let ws = Ws::connect("ws://localhost:8545").await.unwrap();
let ws_provider = Provider::new(ws).interval(Duration::from_millis(100));
Arc::new(ws_provider)
}
pub async fn create_v2_pool(pool_address: Address, client: &Arc<Provider<Ws>>) -> Pool {
let pool_contract = super::contracts::get_pair_v2_contract(&pool_address, client);
let token_0 = pool_contract.token_0().call().await.unwrap();
let token_1 = pool_contract.token_1().call().await.unwrap();
Pool::new(
pool_address,
token_0,
token_1,
U256::from(3000),
PoolVariant::UniswapV2,
)
}
pub async fn create_v3_pool(pool_address: Address, client: &Arc<Provider<Ws>>) -> Pool {
let pool = UniswapV3Pool::new(pool_address, client.into());
let token_0 = pool.token_0().call().await.unwrap();
let token_1 = pool.token_1().call().await.unwrap();
let fee = pool.fee().call().await.unwrap();
Pool::new(
pool_address,
token_0,
token_1,
U256::from(fee),
PoolVariant::UniswapV3,
)
}
/// Override an address's weth balance
pub fn mutate_weth_balance(
state: &mut call_raw::spoof::State,
address_to_mutate: Address,
mutate_amount: U256,
) {
let key = super::u256_to_h256_be(
U256::from_str_radix(
"ffa74f65cef4257058238f071cd4f631a58040052dd622d00aa7a451153252f4",
16,
)
.unwrap(),
);
// Spoofing WETH balance
// cast index address [address] 3 : WETH (give our sandwich contract 100weth)
let val = super::u256_to_h256_be(U256::from("100000000000000000000"));
// Give our acc a fuckton of WETH
state
.account(super::constants::get_weth_address())
.store(key, val);
state.account(address_to_mutate).balance(mutate_amount);
}
pub async fn get_weth_balance_at_block(block: u64) -> U256 {
let (fork, _instance) = create_fork_ws(block).await;
let weth_contract = Erc20::new(get_weth_address(), fork);
let owner = get_sandwich_contract_address();
weth_contract.balance_of(owner).call().await.unwrap()
}
#[macro_export]
macro_rules! time_function {
($x:expr) => {{
let start = std::time::Instant::now();
let result = $x;
let elapsed = start.elapsed();
println!("Elapsed time: {:?}", elapsed);
result
}};
}