From 4fd412c1cedef145fef760cd96c18a416b88b3bc Mon Sep 17 00:00:00 2001 From: Arr00 Date: Mon, 20 Nov 2023 14:59:01 -0500 Subject: [PATCH] mitigations: off chain signature validator --- .../OffChainSignatureValidator.sol | 8 ++++++- .../OffChainSignatureValidator.t.sol | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/contracts/signature-validators/OffChainSignatureValidator.sol b/contracts/signature-validators/OffChainSignatureValidator.sol index 027372d1..25e327ea 100644 --- a/contracts/signature-validators/OffChainSignatureValidator.sol +++ b/contracts/signature-validators/OffChainSignatureValidator.sol @@ -10,6 +10,7 @@ contract OffChainSignatureValidator is IERC1271 { error NotMemberOfParty(); error InsufficientVotingPower(); error MessageHashMismatch(); + error InvalidSignature(); /// @notice Event emmitted when signing threshold updated event SigningThresholdBpsSet( @@ -56,6 +57,11 @@ contract OffChainSignatureValidator is IERC1271 { Party party = Party(payable(msg.sender)); address signer = ecrecover(hash, v, r, s); + + if (signer == address(0)) { + revert InvalidSignature(); + } + uint96 signerVotingPowerBps = party.getVotingPowerAt(signer, uint40(block.timestamp)) * 10000; @@ -70,7 +76,7 @@ contract OffChainSignatureValidator is IERC1271 { // Either threshold is 0 or signer votes above threshold if ( thresholdBps == 0 || - (signerVotingPowerBps > totalVotingPower && + (signerVotingPowerBps >= totalVotingPower && signerVotingPowerBps / totalVotingPower >= thresholdBps) ) { return IERC1271.isValidSignature.selector; diff --git a/test/signature-validators/OffChainSignatureValidator.t.sol b/test/signature-validators/OffChainSignatureValidator.t.sol index 962eadf3..06f2fdb2 100644 --- a/test/signature-validators/OffChainSignatureValidator.t.sol +++ b/test/signature-validators/OffChainSignatureValidator.t.sol @@ -186,6 +186,28 @@ contract OffChainSignatureValidatorTest is SetupPartyHelper { assertEq(abi.decode(res, (bytes4)), IERC1271.isValidSignature.selector); } + function testOffChainSignatureValidator_invalidSignature() public { + string memory message = "Hello, this is my message"; + bytes memory encondedMessage = abi.encodePacked(message); + bytes memory encodedPacket = abi.encodePacked( + "\x19Ethereum Signed Message:\n", + Strings.toString(encondedMessage.length), + encondedMessage + ); + bytes32 messageHash = keccak256(encodedPacket); + (, bytes32 r, bytes32 s) = vm.sign(johnPk, messageHash); + bytes memory signature = abi.encodePacked(r, s, uint8(0), message); + + bytes memory staticCallData = abi.encodeWithSelector( + IERC1271.isValidSignature.selector, + messageHash, + signature + ); + vm.startPrank(address(0), address(0)); + vm.expectRevert(OffChainSignatureValidator.InvalidSignature.selector); + address(party).staticcall(staticCallData); + } + function _signMessage( uint256 privateKey, string memory message