Skip to content

feat: CheatcodesExecutor + vm.deployCode #8181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions crates/cheatcodes/assets/cheatcodes.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,18 @@ interface Vm {
#[cheatcode(group = Filesystem)]
function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);

/// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the
/// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
#[cheatcode(group = Filesystem)]
function deployCode(string calldata artifactPath) external returns (address deployedAddress);

/// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the
/// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
///
/// Additionaly accepts abi-encoded constructor arguments.
#[cheatcode(group = Filesystem)]
function deployCode(string calldata artifactPath, bytes calldata constructorArgs) external returns (address deployedAddress);

/// Gets the deployed bytecode from an artifact file. Takes in the relative path to the json file or the path to the
/// artifact in the form of <path>:<contract>:<version> where <contract> and <version> parts are optional.
#[cheatcode(group = Filesystem)]
Expand Down
72 changes: 36 additions & 36 deletions crates/cheatcodes/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ impl Cheatcode for addrCall {
}

impl Cheatcode for getNonce_0Call {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { account } = self;
get_nonce(ccx, account)
}
}

impl Cheatcode for loadCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { target, slot } = *self;
ensure_not_precompile!(&target, ccx);
ccx.ecx.load_account(target)?;
Expand All @@ -84,7 +84,7 @@ impl Cheatcode for loadCall {
}

impl Cheatcode for loadAllocsCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { pathToAllocsJson } = self;

let path = Path::new(pathToAllocsJson);
Expand All @@ -110,7 +110,7 @@ impl Cheatcode for loadAllocsCall {
}

impl Cheatcode for dumpStateCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { pathToStateJson } = self;
let path = Path::new(pathToStateJson);

Expand Down Expand Up @@ -156,28 +156,28 @@ impl Cheatcode for dumpStateCall {
}

impl Cheatcode for sign_0Call {
fn apply_full<DB: DatabaseExt>(&self, _: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, _: &mut CheatsCtxt<DB>) -> Result {
let Self { privateKey, digest } = self;
super::utils::sign(privateKey, digest)
}
}

impl Cheatcode for sign_1Call {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { digest } = self;
super::utils::sign_with_wallet(ccx, None, digest)
}
}

impl Cheatcode for sign_2Call {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { signer, digest } = self;
super::utils::sign_with_wallet(ccx, Some(*signer), digest)
}
}

impl Cheatcode for signP256Call {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { privateKey, digest } = self;
super::utils::sign_p256(privateKey, digest, ccx.state)
}
Expand Down Expand Up @@ -255,7 +255,7 @@ impl Cheatcode for lastCallGasCall {
}

impl Cheatcode for chainIdCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newChainId } = self;
ensure!(*newChainId <= U256::from(u64::MAX), "chain ID must be less than 2^64 - 1");
ccx.ecx.env.cfg.chain_id = newChainId.to();
Expand All @@ -264,15 +264,15 @@ impl Cheatcode for chainIdCall {
}

impl Cheatcode for coinbaseCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newCoinbase } = self;
ccx.ecx.env.block.coinbase = *newCoinbase;
Ok(Default::default())
}
}

impl Cheatcode for difficultyCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newDifficulty } = self;
ensure!(
ccx.ecx.spec_id() < SpecId::MERGE,
Expand All @@ -285,15 +285,15 @@ impl Cheatcode for difficultyCall {
}

impl Cheatcode for feeCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newBasefee } = self;
ccx.ecx.env.block.basefee = *newBasefee;
Ok(Default::default())
}
}

impl Cheatcode for prevrandao_0Call {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newPrevrandao } = self;
ensure!(
ccx.ecx.spec_id() >= SpecId::MERGE,
Expand All @@ -306,7 +306,7 @@ impl Cheatcode for prevrandao_0Call {
}

impl Cheatcode for prevrandao_1Call {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newPrevrandao } = self;
ensure!(
ccx.ecx.spec_id() >= SpecId::MERGE,
Expand All @@ -319,7 +319,7 @@ impl Cheatcode for prevrandao_1Call {
}

impl Cheatcode for blobhashesCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { hashes } = self;
ensure!(
ccx.ecx.spec_id() >= SpecId::CANCUN,
Expand All @@ -332,7 +332,7 @@ impl Cheatcode for blobhashesCall {
}

impl Cheatcode for getBlobhashesCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
ensure!(
ccx.ecx.spec_id() >= SpecId::CANCUN,
Expand All @@ -344,45 +344,45 @@ impl Cheatcode for getBlobhashesCall {
}

impl Cheatcode for rollCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newHeight } = self;
ccx.ecx.env.block.number = *newHeight;
Ok(Default::default())
}
}

impl Cheatcode for getBlockNumberCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.ecx.env.block.number.abi_encode())
}
}

impl Cheatcode for txGasPriceCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newGasPrice } = self;
ccx.ecx.env.tx.gas_price = *newGasPrice;
Ok(Default::default())
}
}

impl Cheatcode for warpCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newTimestamp } = self;
ccx.ecx.env.block.timestamp = *newTimestamp;
Ok(Default::default())
}
}

impl Cheatcode for getBlockTimestampCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.ecx.env.block.timestamp.abi_encode())
}
}

impl Cheatcode for blobBaseFeeCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newBlobBaseFee } = self;
ensure!(
ccx.ecx.spec_id() >= SpecId::CANCUN,
Expand All @@ -395,14 +395,14 @@ impl Cheatcode for blobBaseFeeCall {
}

impl Cheatcode for getBlobBaseFeeCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.ecx.env.block.get_blob_excess_gas().unwrap_or(0).abi_encode())
}
}

impl Cheatcode for dealCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { account: address, newBalance: new_balance } = *self;
let account = journaled_account(ccx.ecx, address)?;
let old_balance = std::mem::replace(&mut account.info.balance, new_balance);
Expand All @@ -413,7 +413,7 @@ impl Cheatcode for dealCall {
}

impl Cheatcode for etchCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { target, newRuntimeBytecode } = self;
ensure_not_precompile!(target, ccx);
ccx.ecx.load_account(*target)?;
Expand All @@ -424,7 +424,7 @@ impl Cheatcode for etchCall {
}

impl Cheatcode for resetNonceCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { account } = self;
let account = journaled_account(ccx.ecx, *account)?;
// Per EIP-161, EOA nonces start at 0, but contract nonces
Expand All @@ -439,7 +439,7 @@ impl Cheatcode for resetNonceCall {
}

impl Cheatcode for setNonceCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { account, newNonce } = *self;
let account = journaled_account(ccx.ecx, account)?;
// nonce must increment only
Expand All @@ -455,7 +455,7 @@ impl Cheatcode for setNonceCall {
}

impl Cheatcode for setNonceUnsafeCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { account, newNonce } = *self;
let account = journaled_account(ccx.ecx, account)?;
account.info.nonce = newNonce;
Expand All @@ -464,7 +464,7 @@ impl Cheatcode for setNonceUnsafeCall {
}

impl Cheatcode for storeCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { target, slot, value } = *self;
ensure_not_precompile!(&target, ccx);
// ensure the account is touched
Expand All @@ -475,7 +475,7 @@ impl Cheatcode for storeCall {
}

impl Cheatcode for coolCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { target } = self;
if let Some(account) = ccx.ecx.journaled_state.state.get_mut(target) {
account.unmark_touch();
Expand All @@ -486,21 +486,21 @@ impl Cheatcode for coolCall {
}

impl Cheatcode for readCallersCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
read_callers(ccx.state, &ccx.ecx.env.tx.caller)
}
}

impl Cheatcode for snapshotCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.ecx.db.snapshot(&ccx.ecx.journaled_state, &ccx.ecx.env).abi_encode())
}
}

impl Cheatcode for revertToCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { snapshotId } = self;
let result = if let Some(journaled_state) = ccx.ecx.db.revert(
*snapshotId,
Expand All @@ -519,7 +519,7 @@ impl Cheatcode for revertToCall {
}

impl Cheatcode for revertToAndDeleteCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { snapshotId } = self;
let result = if let Some(journaled_state) = ccx.ecx.db.revert(
*snapshotId,
Expand All @@ -538,14 +538,14 @@ impl Cheatcode for revertToAndDeleteCall {
}

impl Cheatcode for deleteSnapshotCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { snapshotId } = self;
let result = ccx.ecx.db.delete_snapshot(*snapshotId);
Ok(result.abi_encode())
}
}
impl Cheatcode for deleteSnapshotsCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
ccx.ecx.db.delete_snapshots();
Ok(Default::default())
Expand Down
Loading
Loading