From 10c0997d71bc54383d83dfacd68baa9f21cbbfb0 Mon Sep 17 00:00:00 2001 From: Aiden Park <97845814+adnpark@users.noreply.github.com> Date: Wed, 8 May 2024 01:57:35 +0900 Subject: [PATCH] feat: change contract name and add dummy signature verification (#109) * feat: change contract name and add dummy signature verification * feat: add dummy signature verification to multi chain signer * fmt --------- Co-authored-by: leekt --- ...iSignatureSigner.sol => MultiChainSigner.sol} | 16 +++++++++++++--- ...CDSAValidator.sol => MultiChainValidator.sol} | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) rename src/signer/{MultiSignatureSigner.sol => MultiChainSigner.sol} (83%) rename src/validator/{MultiSignatureECDSAValidator.sol => MultiChainValidator.sol} (84%) diff --git a/src/signer/MultiSignatureSigner.sol b/src/signer/MultiChainSigner.sol similarity index 83% rename from src/signer/MultiSignatureSigner.sol rename to src/signer/MultiChainSigner.sol index fe21f10..de2f5c5 100644 --- a/src/signer/MultiSignatureSigner.sol +++ b/src/signer/MultiChainSigner.sol @@ -20,7 +20,10 @@ struct ECDSAValidatorStorage { address owner; } -contract MultiSignatureECDSASigner is SignerBase { +bytes constant DUMMY_ECDSA_SIG = + hex"fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; + +contract MultiChainSigner is SignerBase { mapping(address => uint256) public usedIds; mapping(bytes32 id => mapping(address wallet => address)) public signer; @@ -70,8 +73,15 @@ contract MultiSignatureECDSASigner is SignerBase { } bytes memory ecdsaSig = sig[0:65]; bytes32 merkleRoot = bytes32(sig[65:97]); - bytes32[] memory proof = abi.decode(sig[97:], (bytes32[])); - require(MerkleProofLib.verify(proof, merkleRoot, userOpHash), "hash is not in proof"); + // if the signature is a dummy signature, then use dummyUserOpHash instead of real userOpHash + if (keccak256(ecdsaSig) == keccak256(DUMMY_ECDSA_SIG)) { + (bytes32 dummyUserOpHash, bytes32[] memory proof) = abi.decode(sig[97:], (bytes32, bytes32[])); + require(MerkleProofLib.verify(proof, merkleRoot, dummyUserOpHash), "hash is not in proof"); + // otherwise, use real userOpHash + } else { + bytes32[] memory proof = abi.decode(sig[97:], (bytes32[])); + require(MerkleProofLib.verify(proof, merkleRoot, userOpHash), "hash is not in proof"); + } // simple ecdsa verification if (owner == ECDSA.recover(merkleRoot, ecdsaSig)) { return SIG_VALIDATION_SUCCESS_UINT; diff --git a/src/validator/MultiSignatureECDSAValidator.sol b/src/validator/MultiChainValidator.sol similarity index 84% rename from src/validator/MultiSignatureECDSAValidator.sol rename to src/validator/MultiChainValidator.sol index 7c8ae6a..0c9dfb2 100644 --- a/src/validator/MultiSignatureECDSAValidator.sol +++ b/src/validator/MultiChainValidator.sol @@ -19,7 +19,10 @@ struct ECDSAValidatorStorage { address owner; } -contract MultiSignatureECDSAValidator is IValidator, IHook { +bytes constant DUMMY_ECDSA_SIG = + hex"fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; + +contract MultiChainValidator is IValidator, IHook { event OwnerRegistered(address indexed kernel, address indexed owner); mapping(address => ECDSAValidatorStorage) public ecdsaValidatorStorage; @@ -69,8 +72,15 @@ contract MultiSignatureECDSAValidator is IValidator, IHook { } bytes memory ecdsaSig = sig[0:65]; bytes32 merkleRoot = bytes32(sig[65:97]); - bytes32[] memory proof = abi.decode(sig[97:], (bytes32[])); - require(MerkleProofLib.verify(proof, merkleRoot, userOpHash), "hash is not in proof"); + // if the signature is a dummy signature, then use dummyUserOpHash instead of real userOpHash + if (keccak256(ecdsaSig) == keccak256(DUMMY_ECDSA_SIG)) { + (bytes32 dummyUserOpHash, bytes32[] memory proof) = abi.decode(sig[97:], (bytes32, bytes32[])); + require(MerkleProofLib.verify(proof, merkleRoot, dummyUserOpHash), "hash is not in proof"); + // otherwise, use real userOpHash + } else { + bytes32[] memory proof = abi.decode(sig[97:], (bytes32[])); + require(MerkleProofLib.verify(proof, merkleRoot, userOpHash), "hash is not in proof"); + } // simple ecdsa verification if (owner == ECDSA.recover(merkleRoot, ecdsaSig)) { return SIG_VALIDATION_SUCCESS_UINT;