Skip to content

vm.signTypedData or vm.generateEIP712Digest #3330

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

Closed
colinnielsen opened this issue Sep 23, 2022 · 6 comments
Closed

vm.signTypedData or vm.generateEIP712Digest #3330

colinnielsen opened this issue Sep 23, 2022 · 6 comments
Labels
A-cheatcodes Area: cheatcodes C-forge Command: forge T-feature Type: feature

Comments

@colinnielsen
Copy link
Contributor

Component

Forge

Describe the feature you would like

For EIP712 testing, it would be great to have a EIP712 digest generator that creates a 32 byte digest based the types, domain, and values following the algorithm defined in the EIP712 spec, or even a fully built signedTypedData cheatcode.

I've had a lot of headache recently with EIP712 foundry tests passing when they shouldn't have because there was no way to test if a contract is computing a digest properly.

I am not sure what cheatcodes would look like in solidity, but I imagine passing a it:

  1. EIP712 domain struct
  2. The EIP712 type def: eg: Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)
  3. The abi.encodePacked() values of the struct

This could be a possible interface

function generateEIP712Digest(EIP712Domain memory domain, string memory eip712Type, bytes memory structValue) public view returns (string memory);

function signTypedData(uint256 privateKey, EIP712Domain memory domain, string memory eip712Type, bytes memory structValue) public view returns (uint8 v, bytes32 r, bytes32 s);

Additional context

No response

@colinnielsen colinnielsen added the T-feature Type: feature label Sep 23, 2022
@gakonst gakonst added this to Foundry Sep 23, 2022
@gakonst gakonst moved this to Todo in Foundry Sep 23, 2022
@rkrasiuk rkrasiuk added C-forge Command: forge A-cheatcodes Area: cheatcodes labels Sep 25, 2022
@CodeSandwich
Copy link
Contributor

CodeSandwich commented Sep 29, 2022

I had a similar problem, but I was able to work it around with vm.sign(privKey, digest) and OpenZeppelin's helpers. It boiled down to:

bytes32 digest = ECDSA.toTypedDataHash(domainSeparator, keccak256(payload));
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privKey, digest);

It has an advantage over a VM built-in of not enforcing any particular signing convention, it's very elastic and thus future-proof.

@colinnielsen
Copy link
Contributor Author

bytes32 digest = ECDSA.toTypedDataHash(domainSeparator, keccak256(payload));

hmm - yes this does get closer to solving the problem, but I think there is still a use case for true EIP712 digest generation. This would still be easy to generate false positives against.

@CodeSandwich
Copy link
Contributor

By far the best solution would be to have support for EIP-721 in Solidity, it could then do the magic static typing like it does with abi.encodeWithSelector. What can the VM do safer than a Solidity library? Both of them can analyze the string memory eip712Type and try to parse the bytes memory structValue to sanity-check it, but it seems like that's about it. That's an awesome feature when writing tests, but it doesn't seem to require a forever change in the VM API, a Solidity library should do just fine.

I mean, don't mind my opinion too much, I'm not a Foundry developer, so it's not up to me to make any decisions, I'm just a user who wants to have Foundry robust.

@mds1
Copy link
Collaborator

mds1 commented Mar 9, 2023

There's no easy way in solidity to have a generic EIP-712 cheat since the data being signed over varies with each implementation. Instead, you should write your own helper contracts based on your specific contract. See https://book.getfoundry.sh/tutorials/testing-eip712 for an example of how to do this

@mds1 mds1 closed this as not planned Won't fix, can't repro, duplicate, stale Mar 9, 2023
@github-project-automation github-project-automation bot moved this from Todo to Done in Foundry Mar 9, 2023
@vseehausen
Copy link

vseehausen commented Sep 30, 2023

There is an open proposal to add this as a core feature to solidity: ethereum/solidity#14157

I think it makes a lot of sense because the work to implement correct hashes is labor-intensive and error-prone. Mostly, because you have to generate a lot of typehashes. With nested structs, the labor and the error proneness increase exponentially. Javascript libraries have this included, so currently the best guess to test your typehashes is to include some JS into your repo.

Either way, it would be awesome to be able to test this natively in foundry.

It would even help a lot to have a library that generates the type hashes. As a step.

@aviggiano
Copy link

aviggiano commented Apr 8, 2025

Hello, I'd like to reopen this issue.

I am building safe-utils in order to automate the proposal of Safe transactions through Foundry, and one common use case is Safe signers who use Ledger wallets. It seems that I cannot simply vm.sign on Ledger devices, so a vm.signTypedData would be needed.

Update: I opened a specific issue #10281

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cheatcodes Area: cheatcodes C-forge Command: forge T-feature Type: feature
Projects
Archived in project
Development

No branches or pull requests

6 participants