Skip to content

feat(forge): implement vm.signTypedData cheatcode #10330

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

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions crates/cheatcodes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@ tracing.workspace = true
walkdir.workspace = true
proptest.workspace = true
serde.workspace = true

20 changes: 20 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.

4 changes: 4 additions & 0 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2651,6 +2651,10 @@ interface Vm {
#[cheatcode(group = Crypto)]
function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);

/// Signs Human-Readable Typed Data with `privateKey` using the secp256k1 curve.
#[cheatcode(group = Crypto)]
function signTypedData(string calldata jsonData, uint256 privateKey) external pure returns (uint8 v, bytes32 r,bytes32 s);

/// Signs `digest` with `privateKey` using the secp256k1 curve.
///
/// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the
Expand Down
11 changes: 11 additions & 0 deletions crates/cheatcodes/src/crypto.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Implementations of [`Crypto`](spec::Group::Crypto) Cheatcodes.

use crate::{Cheatcode, Cheatcodes, Result, Vm::*};
use alloy_dyn_abi::eip712::TypedData;
use alloy_primitives::{keccak256, Address, B256, U256};
use alloy_signer::{Signer, SignerSync};
use alloy_signer_local::{
Expand Down Expand Up @@ -51,6 +52,16 @@ impl Cheatcode for sign_0Call {
}
}

impl Cheatcode for signTypedDataCall {
fn apply(&self, _state: &mut Cheatcodes) -> Result {
let Self { jsonData, privateKey } = self;
let typed_data: TypedData = serde_json::from_str(jsonData)?;
let digest = typed_data.eip712_signing_hash()?;
let sig = sign(privateKey, &digest)?;
Ok(encode_full_sig(sig))
}
}

impl Cheatcode for signCompact_0Call {
fn apply(&self, _state: &mut Cheatcodes) -> Result {
let Self { wallet, digest } = self;
Expand Down
3 changes: 2 additions & 1 deletion crates/evm/traces/src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,12 @@ impl CallTraceDecoder {

Some(decoded.iter().map(format_token).collect())
}
"signDelegation" | "signAndAttachDelegation" => {
"signDelegation" | "signAndAttachDelegation" | "signTypedData" => {
let mut decoded = func.abi_decode_input(&data[SELECTOR_LEN..], false).ok()?;
// Redact private key and replace in trace for
// signAndAttachDelegation(address implementation, uint256 privateKey)
// signDelegation(address implementation, uint256 privateKey)
// signTypedData(string jsonData, uint256 privateKey)
decoded[1] = DynSolValue::String("<pk>".to_string());
Some(decoded.iter().map(format_token).collect())
}
Expand Down
1 change: 1 addition & 0 deletions testdata/cheats/Vm.sol

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

Loading