2022-07-03 14:41:42 -07:00
|
|
|
// test/Messages.sol
|
|
|
|
// SPDX-License-Identifier: Apache 2
|
|
|
|
|
|
|
|
pragma solidity ^0.8.0;
|
|
|
|
|
|
|
|
import "../contracts/Messages.sol";
|
2022-08-04 08:58:49 -07:00
|
|
|
import "../contracts/Structs.sol";
|
2022-07-03 14:41:42 -07:00
|
|
|
import "forge-std/Test.sol";
|
|
|
|
|
2023-01-11 09:32:48 -08:00
|
|
|
contract TestMessages is Test {
|
|
|
|
uint256 constant testGuardian = 93941733246223705020089879371323733820373732307041878556247502674739205313440;
|
|
|
|
|
|
|
|
Messages messages;
|
|
|
|
|
|
|
|
Structs.GuardianSet guardianSet;
|
|
|
|
|
|
|
|
function setUp() public {
|
|
|
|
messages = new Messages();
|
|
|
|
|
|
|
|
// initialize guardian set with one guardian
|
|
|
|
address[] memory keys = new address[](1);
|
|
|
|
keys[0] = vm.addr(testGuardian);
|
|
|
|
guardianSet = Structs.GuardianSet(keys, 0);
|
|
|
|
require(messages.quorum(guardianSet.keys.length) == 1, "Quorum should be 1");
|
|
|
|
}
|
2022-08-04 08:58:49 -07:00
|
|
|
|
2022-07-03 14:41:42 -07:00
|
|
|
function testQuorum() public {
|
2023-01-11 09:32:48 -08:00
|
|
|
assertEq(messages.quorum(0), 1);
|
|
|
|
assertEq(messages.quorum(1), 1);
|
|
|
|
assertEq(messages.quorum(2), 2);
|
|
|
|
assertEq(messages.quorum(3), 3);
|
|
|
|
assertEq(messages.quorum(4), 3);
|
|
|
|
assertEq(messages.quorum(5), 4);
|
|
|
|
assertEq(messages.quorum(6), 5);
|
|
|
|
assertEq(messages.quorum(7), 5);
|
|
|
|
assertEq(messages.quorum(8), 6);
|
|
|
|
assertEq(messages.quorum(9), 7);
|
|
|
|
assertEq(messages.quorum(10), 7);
|
|
|
|
assertEq(messages.quorum(11), 8);
|
|
|
|
assertEq(messages.quorum(12), 9);
|
|
|
|
assertEq(messages.quorum(19), 13);
|
|
|
|
assertEq(messages.quorum(20), 14);
|
2022-07-03 14:41:42 -07:00
|
|
|
}
|
2022-08-04 08:58:49 -07:00
|
|
|
|
2023-01-11 09:32:48 -08:00
|
|
|
function testQuorumCanAlwaysBeReached(uint256 numGuardians) public {
|
|
|
|
vm.assume(numGuardians > 0);
|
|
|
|
|
2022-08-12 11:36:56 -07:00
|
|
|
if (numGuardians >= 256) {
|
|
|
|
vm.expectRevert("too many guardians");
|
|
|
|
}
|
|
|
|
// test that quorums is never greater than the number of guardians
|
2023-01-11 09:32:48 -08:00
|
|
|
assert(messages.quorum(numGuardians) <= numGuardians);
|
2022-08-12 11:36:56 -07:00
|
|
|
}
|
|
|
|
|
2023-01-11 09:32:48 -08:00
|
|
|
// This test ensures that submitting more signatures than expected will
|
|
|
|
// trigger a "guardian index out of bounds" error.
|
|
|
|
function testCannotVerifySignaturesWithOutOfBoundsSignature(bytes memory encoded) public {
|
|
|
|
vm.assume(encoded.length > 0);
|
|
|
|
|
|
|
|
bytes32 message = keccak256(encoded);
|
|
|
|
|
|
|
|
// First generate a legitimate signature.
|
|
|
|
Structs.Signature memory goodSignature = Structs.Signature(message, 0, 0, 0);
|
|
|
|
(goodSignature.v, goodSignature.r, goodSignature.s) = vm.sign(testGuardian, message);
|
|
|
|
assertEq(ecrecover(message, goodSignature.v, goodSignature.r, goodSignature.s), vm.addr(testGuardian));
|
|
|
|
|
|
|
|
// Reuse legitimate signature above for the next signature. This will
|
|
|
|
// bypass the "invalid signature" revert.
|
|
|
|
Structs.Signature memory outOfBoundsSignature = goodSignature;
|
|
|
|
outOfBoundsSignature.guardianIndex = 1;
|
|
|
|
|
|
|
|
// Attempt to verify signatures.
|
|
|
|
Structs.Signature[] memory sigs = new Structs.Signature[](2);
|
|
|
|
sigs[0] = goodSignature;
|
|
|
|
sigs[1] = outOfBoundsSignature;
|
|
|
|
|
|
|
|
vm.expectRevert("guardian index out of bounds");
|
|
|
|
messages.verifySignatures(message, sigs, guardianSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This test ensures that submitting an invalid signature fails when
|
|
|
|
// verifySignatures is called. Calling ecrecover should fail.
|
|
|
|
function testCannotVerifySignaturesWithInvalidSignature(bytes memory encoded) public {
|
|
|
|
vm.assume(encoded.length > 0);
|
|
|
|
|
|
|
|
bytes32 message = keccak256(encoded);
|
|
|
|
|
|
|
|
// Generate an invalid signature.
|
|
|
|
Structs.Signature memory badSignature = Structs.Signature(message, 0, 0, 0);
|
|
|
|
assertEq(ecrecover(message, badSignature.v, badSignature.r, badSignature.s), address(0));
|
|
|
|
|
|
|
|
// Attempt to verify signatures.
|
|
|
|
Structs.Signature[] memory sigs = new Structs.Signature[](2);
|
|
|
|
sigs[0] = badSignature;
|
|
|
|
|
|
|
|
vm.expectRevert("ecrecover failed with signature");
|
|
|
|
messages.verifySignatures(message, sigs, guardianSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testVerifySignatures(bytes memory encoded) public {
|
|
|
|
vm.assume(encoded.length > 0);
|
|
|
|
|
|
|
|
bytes32 message = keccak256(encoded);
|
|
|
|
|
|
|
|
// Generate legitimate signature.
|
|
|
|
Structs.Signature memory goodSignature;
|
|
|
|
(goodSignature.v, goodSignature.r, goodSignature.s) = vm.sign(testGuardian, message);
|
|
|
|
assertEq(ecrecover(message, goodSignature.v, goodSignature.r, goodSignature.s), vm.addr(testGuardian));
|
|
|
|
goodSignature.guardianIndex = 0;
|
|
|
|
|
|
|
|
// Attempt to verify signatures.
|
|
|
|
Structs.Signature[] memory sigs = new Structs.Signature[](1);
|
|
|
|
sigs[0] = goodSignature;
|
|
|
|
|
|
|
|
(bool valid, string memory reason) = messages.verifySignatures(message, sigs, guardianSet);
|
|
|
|
assertEq(valid, true);
|
|
|
|
assertEq(bytes(reason).length, 0);
|
2022-08-04 08:58:49 -07:00
|
|
|
}
|
2022-07-03 14:41:42 -07:00
|
|
|
}
|