From 2bbe7932f306e303deb14657c0972f1e5c5af36f Mon Sep 17 00:00:00 2001 From: Dirk Brink Date: Wed, 15 Nov 2023 17:00:44 -0800 Subject: [PATCH] ethereum: Add verifyCurrentQuorum method to core bridge --- ethereum/contracts/Messages.sol | 40 ++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/ethereum/contracts/Messages.sol b/ethereum/contracts/Messages.sol index c70efbb6a1..61e53acdc3 100644 --- a/ethereum/contracts/Messages.sol +++ b/ethereum/contracts/Messages.sol @@ -103,7 +103,7 @@ contract Messages is Getters { /** - * @dev verifySignatures serves to validate arbitrary sigatures against an arbitrary guardianSet + * @dev verifySignatures serves to validate arbitrary signatures against an arbitrary guardianSet * - it intentionally does not solve for expectations within guardianSet (you should use verifyVM if you need these protections) * - it intentioanlly does not solve for quorum (you should use verifyVM if you need these protections) * - it intentionally returns true when signatures is an empty set (you should use verifyVM if you need these protections) @@ -140,6 +140,44 @@ contract Messages is Getters { return (true, ""); } + /** + * @dev verifyCurrentQuorum serves to validate arbitrary signatures and check quorum against the current guardianSet + */ + function verifyCurrentQuorum(bytes32 hash, Structs.Signature[] memory signatures) public view returns (bool valid, string memory response) { + uint32 gsi = getCurrentGuardianSetIndex(); + Structs.GuardianSet memory guardianSet = getGuardianSet(gsi); + + /** + * @dev Checks whether the guardianSet has zero keys + * WARNING: This keys check is critical to ensure the guardianSet has keys present AND to ensure + * that guardianSet key size doesn't fall to zero and negatively impact quorum assessment. If guardianSet + * key length is 0 and vm.signatures length is 0, this could compromise the integrity of both vm and + * signature verification. + */ + if(guardianSet.keys.length == 0){ + return (false, "invalid guardian set"); + } + + /** + * @dev We're using a fixed point number transformation with 1 decimal to deal with rounding. + * WARNING: This quorum check is critical to assessing whether we have enough Guardian signatures to validate a VM + * if making any changes to this, obtain additional peer review. If guardianSet key length is 0 and + * vm.signatures length is 0, this could compromise the integrity of both vm and signature verification. + */ + if (signatures.length < quorum(guardianSet.keys.length)){ + return (false, "no quorum"); + } + + /// @dev Verify the proposed vm.signatures against the guardianSet + (bool signaturesValid, string memory invalidReason) = verifySignatures(hash, signatures, guardianSet); + if(!signaturesValid){ + return (false, invalidReason); + } + + /// If we are here, we've validated the VM is a valid multi-sig that matches the current guardianSet. + return (true, ""); + } + /** * @dev parseVM serves to parse an encodedVM into a vm struct * - it intentionally performs no validation functions, it simply parses raw into a struct