Skip to content

Commit

Permalink
[ChainUtils] Add utilities to create vanity address contract using CR…
Browse files Browse the repository at this point in the history
…EATE2.
  • Loading branch information
10xc0ffee committed Sep 11, 2023
1 parent 01a9737 commit 9993385
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 4 deletions.
1 change: 1 addition & 0 deletions bot/crates/strategy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ futures = "0.3.5"
async-trait = "0.1.64"
anyhow = "1.0.70"
serde = "1.0.145"
dotenv = "0.15.0"

# EVM based crates
cfmms = { git = "https://github.com/zayg/cfmms-rs.git", branch = "fix-serialize-dex-fee"}
Expand Down
157 changes: 153 additions & 4 deletions bot/crates/strategy/src/common/chain_utils.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
use ethers::{
abi::{Function, Param, ParamType, StateMutability, Token},
prelude::{abigen, Abigen},
providers::{Middleware, ProviderError},
types::{BlockNumber, Address, U64, NameOrAddress, BlockId}
signers::{LocalWallet, Signer},
middleware::SignerMiddleware,
types::{BlockNumber, Address, U64, NameOrAddress, BlockId, Bytes, H256, Eip1559TransactionRequest, TransactionRequest}, abi::AbiEncode
};
/*
use foundry_evm::executor::{
fork::{BlockchainDb, BlockchainDbMeta, SharedBackend},
ExecutionResult,
Output,
TxEnv,
TransactTo, BlockEnv
};
use foundry_evm::revm::{
db::CacheDB,
primitives::{Address as rAddress, U256 as rU256},
EVM
};
*/
use log::{info, debug};
use std::sync::Arc;
use std::{collections::BTreeSet, str::FromStr, sync::Arc, error::Error};

use crate::types::BlockInfo;

pub async fn get_inception_block<M: Middleware>(
contract: Address,
Expand Down Expand Up @@ -54,12 +74,117 @@ pub async fn get_inception_block<M: Middleware>(
return Ok(BlockNumber::Number(start_block));
}

pub async fn create_contract_with_vanity_address<M: Middleware>(
expected_addr_prefix: &str,
code_to_deploy: &str,
wallet: &LocalWallet,
provider: Arc<M>) -> Result<(), Box<dyn Error>>
where M: 'static
{
abigen!(
ImmutableCreate2Factory,
r#"[
function safeCreate2(bytes32 salt, bytes calldata initializationCode) external payable containsCaller(salt) returns (address deploymentAddress)
function findCreate2Address(bytes32 salt, bytes calldata initCode) external view returns (address deploymentAddress)
function hasBeenDeployed(address deploymentAddress) external view returns (bool)
]"#
);
let safe_create2_factory =
Address::from_str("0x0000000000FFe8B47B3e2130213B802212439497").unwrap();
let safe_create2_contract =
ImmutableCreate2Factory::new(safe_create2_factory, provider.clone());
let mut found_expected_prefix = false;
let mut salt: H256 = H256::zero();
while !found_expected_prefix {
let prefix = format!("{:#x}", safe_create2_factory);
let random = format!("{:#x}", H256::random());
let tmp_salt =
format!("{}{}",
prefix.get(0..).unwrap(),
random.get(2..26).unwrap());
salt = tmp_salt.parse().unwrap();
if let Ok(address) = safe_create2_contract
.find_create_2_address(
salt.into(),
Bytes::from_str(code_to_deploy)?)
.call().await
{
log::debug!("Dry run contract create at address {address:?} with salt {salt:?}");
let addr_str: String = address.to_string();
if addr_str.find(expected_addr_prefix) == Some(0) {
if let Ok(deployed) = safe_create2_contract
.has_been_deployed(
address)
.call().await
{
if !deployed {
found_expected_prefix = true;
}
}
}
};
}

/*
// Simulate the transaction in local EVM to get the gas estimation.
let shared_backend =
SharedBackend::spawn_backend_thread(
provider.clone(),
BlockchainDb::new(
BlockchainDbMeta {
cfg_env: Default::default(),
block_env: Default::default(),
hosts: BTreeSet::from(["".to_string()])
},
None
),
Some(BlockId::Number(BlockNumber::Latest)));
let fork_db = CacheDB::new(shared_backend);
let mut evm = EVM::new();
evm.database(fork_db);
*/
let client =
SignerMiddleware::new(provider.clone(), wallet.clone());
//safeCreate2(bytes32,bytes calldata) external payable returns (address deploymentAddress)
#[allow(deprecated)]
let function = Function {
name: "safeCreate2".to_owned(),
inputs: vec![
Param { name: "".to_owned(), kind: ParamType::FixedBytes(32), internal_type: None },
Param { name: "".to_owned(), kind: ParamType::Bytes, internal_type: None },
],
outputs: vec![
Param {name: "".to_owned(), kind: ParamType::Address, internal_type: None},
],
constant: Some(false),
state_mutability: StateMutability::Payable
};
let encoded_salt = Token::FixedBytes(salt.to_fixed_bytes().into());
let encoded_code = Token::Bytes(code_to_deploy.into());
log::info!("Function signature {:?}", function.signature());
let tx =
TransactionRequest::new()
.to(safe_create2_factory)
.value(500000000000000000u64)
.gas(2000000)
.data(function.encode_input(&[encoded_salt, encoded_code]).unwrap());
//let tx =
// client.send_transaction(tx, None).await?.await?;
log::info!("Completed Transaction. Receipt: {tx:?}");
Ok(())
}

#[cfg(test)]
mod tests {
use std::error::Error;
use std::str::FromStr;
use std::{
error::Error,
str::FromStr,
env
};
use ethers::providers::{Provider, Ws};
use env_logger;
use dotenv::dotenv;
use anyhow::{anyhow, Result};
use super::*;

// For some reason, the url below couldn't fetch code from the last 128 blocks.
Expand All @@ -79,4 +204,28 @@ mod tests {
assert_eq!(block.as_number().unwrap().as_u64(), 12771526u64);
return Ok(());
}

#[tokio::test]
async fn test_create_sando_huff() -> Result<(), Box<dyn Error>>
{
dotenv().ok();

let get_env = |var| {
env::var(var).map_err(|_| anyhow!("Required environment variable \"{}\" not set", var))
};

let searcher_signer = get_env("SEARCHER_PRIVATE_KEY")?
.parse::<LocalWallet>()
.map_err(|_| anyhow!("Failed to parse \"SEARCHER_PRIVATE_KEY\""))?;

let url: &str = "ws://192.168.0.12:8545/";
let provider =
Arc::new(Provider::new(Ws::connect(url).await?));

// The code is generated by "huffc src/sando.huff --bytecode"
let code_to_deploy = "61085d80600a3d393df35f355f1a565b6104d0565b610624565b61057a565b6106e5565b61043a565b6102d1565b61038c565b61022e565b6107a6565b6107c6565b6107ec56000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b6099357fff000000000000000000000000000000000000000000000000000000000000005f527f1f98431c8ad98523631ae4a59f267346ea31f98400000000000000000000000046526015527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460355260555f2073ffffffffffffffffffffffffffffffffffffffff16331415610858575f5f60445f5f7effffffffffffffffffffffffffffffffffffffff00000000000000000000006084351660581c60843560f81c6101f8577fa9059cbb000000000000000000000000000000000000000000000000000000005f52336004526024356024525af11561085857005b7fa9059cbb000000000000000000000000000000000000000000000000000000005f52336004526004356024525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60f95f5f463560601c7f128acb08000000000000000000000000000000000000000000000000000000005f5230600452620186a0340260445273fffd8963efd1fc6a506488495d951d5263988d2560645260a0608452603560a45273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260581b60c45260153560d9525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60f95f5f463560601c7f128acb08000000000000000000000000000000000000000000000000000000005f52306004526001602452620186a034026044526401000276ad60645260a0608452603560a4527f010000000000000000000000000000000000000000000000000000000000000073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260581b0160c45260153560d9525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60f95f5f463560601c7f128acb08000000000000000000000000000000000000000000000000000000005f523060045260016024526049358060081b905f1a526401000276ad60645260a0608452603560a4527f010000000000000000000000000000000000000000000000000000000000000060153560601c60581b0160c45260293560d9525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60f95f5f463560601c7f128acb08000000000000000000000000000000000000000000000000000000005f52306004526049358060081b905f1a5273fffd8963efd1fc6a506488495d951d5263988d2560645260a0608452603560a45260153560601c60581b60c45260293560d9525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60a45f5f463560601c5f5f7fa9059cbb000000000000000000000000000000000000000000000000000000005f52826004526029358060081b905f1a5260445f5f60153560601c5af1507f022c0d9f000000000000000000000000000000000000000000000000000000005f52620186a034026004525f6024523060445260806064525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60a45f5f463560601c5f5f7fa9059cbb000000000000000000000000000000000000000000000000000000005f52826004526029358060081b905f1a5260445f5f60153560601c5af1507f022c0d9f000000000000000000000000000000000000000000000000000000005f525f600452620186a034026024523060445260806064525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60a45f5f463560601c5f5f7f23b872dd000000000000000000000000000000000000000000000000000000005f523060045282602452620186a0340260445260645f5f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af1507f022c0d9f000000000000000000000000000000000000000000000000000000005f525f6004525f6024526015358060081b905f1a523060445260806064525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f60a45f5f463560601c5f5f7f23b872dd000000000000000000000000000000000000000000000000000000005f523060045282602452620186a0340260445260645f5f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af1507f022c0d9f000000000000000000000000000000000000000000000000000000005f525f6004526015358060081b905f1a525f6024523060445260806064525af11561085857005b73e65575c0e8abd40d32c4c0fb528c5569b53401353314156108585733ff005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858575f5f5f5f47335af1005b73e65575c0e8abd40d32c4c0fb528c5569b5340135331415610858577fa9059cbb0000000000000000000000000000000000000000000000000000000059523360045246356024525f5f60445f5f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af11561085857005b600380fd";
create_contract_with_vanity_address(
"", &code_to_deploy, &searcher_signer, provider.clone()).await?;
return Ok(());
}
}

0 comments on commit 9993385

Please sign in to comment.