use alloy_primitives::{Address, U256};
use anyhow::Result;
use evm_fork_cache::deploy::{encode_constructor_args, etch_foundry_artifact_or_create};
#[path = "support/mock.rs"]
mod mock;
const ARTIFACT: &str = concat!(
env!("CARGO_MANIFEST_DIR"),
"/fixtures/MockERC20.foundry.json"
);
const CREATE_ADDRESS_ZERO_NONCE_0: Address = Address::new(alloy_primitives::hex!(
"bd770416a3345f91e4b34576cb804a576fa48eb1"
));
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
let mut cache = mock::offline_cache().await?;
mock::install_default_account(&mut cache, Address::ZERO);
mock::install_default_account(&mut cache, CREATE_ADDRESS_ZERO_NONCE_0);
let target = Address::repeat_byte(0xCC);
let holder = Address::repeat_byte(0xDD);
mock::install_mock_erc20(&mut cache, target);
mock::install_default_account(&mut cache, holder);
cache.insert_mapping_storage_slot(
target,
U256::from(mock::MOCK_ERC20_BALANCE_SLOT),
holder,
U256::from(7_777u64),
)?;
println!(
"target {target} holder balance (before etch): {}",
mock::balance_of(&mut cache, target, holder)?
);
let constructor_args = encode_constructor_args((
String::from("Etched Token"),
String::from("ETCH"),
U256::from(18u8),
));
let etched = etch_foundry_artifact_or_create(
&mut cache,
target,
ARTIFACT,
Address::ZERO,
constructor_args,
)?;
println!(
"etched {} bytes from {} over {}",
etched.code_size, etched.deployed_address, etched.target_address,
);
println!(
"target holder balance (after etch): {} (storage preserved)",
mock::balance_of(&mut cache, target, holder)?
);
assert_eq!(
mock::balance_of(&mut cache, target, holder)?,
U256::from(7_777u64),
"etching runtime bytecode must preserve the target's storage"
);
Ok(())
}