Description
I'm trying to recover the signature object properties (uint8 v, bytes32 r, bytes32 s) from a signature hash. I'm creating the signature in Foundry as follows.
function testLockRequestSignatureRecovery() external {
(address guardian, bytes guardianPK) = vm.getAddrAndKey("guardian");
// SETUP
vm.startPrank(guardian);
bytes32 lockRequest = accountLock.createLockRequest(account);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(guardianPK, lockRequest);
bytes memory signature = abi.encodePacked(v, r, s);
address guardianRecovered = ECDSA.recover(lockRequest, signature); // throws error "ECDSA: invalid signature 'v' value"
address guardianRecovered = ECDSA.recover(lockRequest, v, r, s); // works!
💻 Environment
Framework: Foundry
📝 Details
When calling ECDSA.recover(lockRequest, signature)
the ECDSA contract tries to first retrieve the v, r, s
values from the signature
using the function tryRecover(bytes32 hash, bytes memory signature)
which further calls tryRecover(hash, v, r, s)
which throws the error indicating invalid value of v
, whereas if I bypass the function tryRecover(bytes32 hash, bytes memory signature)
and directly call the ECDSA.tryRecover(hash, v, r, s)
function, it works. That concludes that the value of v
retrieved by vm.sign(guardianPK, lockRequest)
is correct. I can even see it in my logs that v = 27
which is a valid value:
VM::sign(<pk>, 0x46a4a6b86560880572154cc245188597806bacb2ed65aa43fdd0c670c5f762dc) [staticcall]
│ └─ ← 27, 0x1b5ae0bf91052a8ac3cfbc285fb915cca056865a1db7b832b851e2907107540b, 0x01a519d1066a48c2f4e43fb12f35144065c7dc82ee057f284502d34908703ca5
└─ ← "ECDSA: invalid signature 'v' value"
🔢 Code to reproduce bug
https://github.com/alfheimrShiven/smart-wallet
🐞Cmd to reproduce bug
forge test --mt testLockRequestConcensysEvaluation -vvvv