#![expect(clippy::expect_used, clippy::panic, clippy::print_stdout)]
use alloy::primitives::{utils::keccak256, Address, Bytes, TxKind, B256};
use revm::context::Context;
use revm::context::TxEnv;
use revm::context_interface::result::{ExecutionResult, Output};
use revm::context_interface::ContextTr;
use revm::database::CacheDB;
use revm::database_interface::EmptyDB;
use revm::Database;
use revm::{ExecuteCommitEvm, ExecuteEvm, MainBuilder, MainContext};
fn repo_root() -> std::path::PathBuf {
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../../..")
.canonicalize()
.expect("canonicalize repo root")
}
fn load_hex(rel: &str) -> Vec<u8> {
let raw = std::fs::read_to_string(repo_root().join(rel))
.unwrap_or_else(|e| panic!("missing {rel}: {e}"));
let s: String = raw.trim().chars().filter(|c| *c != '\n').collect();
assert!(s.len().is_multiple_of(2), "{rel}: odd hex length");
(0..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("hex byte"))
.collect()
}
fn deploy_args(weth: Address, pool_manager: Address) -> Vec<u8> {
let mut args = vec![0u8; 64];
args[12..32].copy_from_slice(weth.as_slice());
args[44..64].copy_from_slice(pool_manager.as_slice());
args
}
#[test]
fn executor_deploys_with_two_constructor_args_and_embeds_computed_immutables() {
let weth = Address::repeat_byte(0x11);
let pool_manager = Address::repeat_byte(0x22);
let mut init = load_hex("tier3-oracle/artifacts/executor/cmd_executor.creation.hex");
init.extend_from_slice(&deploy_args(weth, pool_manager));
let db = CacheDB::new(EmptyDB::default());
let mut evm = Context::mainnet().with_db(db).build_mainnet();
evm.ctx.cfg.disable_nonce_check = true;
let res = evm
.transact(
TxEnv::builder()
.kind(TxKind::Create)
.gas_limit(16_000_000)
.data(Bytes::from(init))
.build()
.expect("deploy tx"),
)
.expect("deploy transact");
let executor = match &res.result {
ExecutionResult::Success {
output: Output::Create(_, Some(addr)),
..
} => *addr,
other => panic!("executor deploy failed: {other:?}"),
};
evm.commit(res.state);
let self_bytes = B256::left_padding_from(executor.as_slice());
let weth_bytes = B256::left_padding_from(weth.as_slice());
let expected_weth_delta = keccak256([self_bytes.as_slice(), weth_bytes.as_slice()].concat());
let expected_native_delta = keccak256([self_bytes.as_slice(), B256::ZERO.as_slice()].concat());
let code = evm
.ctx
.db_mut()
.basic(executor)
.expect("db basic")
.expect("no executor account")
.code
.map(|c| c.original_bytes().to_vec())
.expect("deployed executor has no code");
assert!(!code.is_empty(), "deployed executor has empty runtime code");
println!(
"executor deployed at {executor}; runtime {} bytes",
code.len()
);
let has = |needle: &[u8]| code.windows(needle.len()).any(|w| w == needle);
assert!(
has(expected_weth_delta.as_slice()),
"WETH_DELTA_SLOT immutable not found in deployed executor code"
);
assert!(
has(expected_native_delta.as_slice()),
"NATIVE_DELTA_SLOT immutable not found in deployed executor code"
);
assert!(
has(weth.as_slice()),
"WETH_ADDR immutable not found in deployed executor code"
);
assert!(
has(pool_manager.as_slice()),
"POOL_MANAGER_ADDR immutable not found in deployed executor code"
);
}