Commit 040c34f7 authored by Maurelian's avatar Maurelian

test(ctb): Add approved hash checking to GetSigners test

working for approvedHashes
parent 411da0fd
......@@ -9,21 +9,19 @@ import "test/safe-tools/SafeTestTools.sol";
import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol";
contract GetSigners_Test is Test, SafeTestTools, GetSigners {
struct SigTypeCount {
uint256 numEoaSigs;
uint256 numEthSignSigs;
uint256 numApprovedHashSigs;
uint256 numContractSigs;
}
bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;
enum SigType {
enum SigTypes {
Eoa,
EthSign,
ApprovedHash,
Contract
ApprovedHash //,
// Contract
}
mapping(uint256 => SigType) public sigTypes;
function sigType(uint256 _key) internal view returns (SigTypes sigType_) {
uint256 t = _key % 3; //4;
sigType_ = SigTypes(t);
}
/// @dev Test that for a given set of signatures:
/// 1. safe.checkNSignatures() succeeds
......@@ -32,35 +30,11 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners {
/// Demonstrating these three properties is sufficient to prove that the getSigners() method
/// returns the same signatures as those recovered by safe.checkNSignatures().
/// todo(maurelian): include tests for EIP1271 signatures, and contract signatures.
function testDiff_getSignaturesVsCheckSignatures_succeeds(bytes32 _digest, SigTypeCount memory _split) external {
function testDiff_getSignaturesVsCheckSignatures_succeeds(bytes32 _digest, uint256 _numSigs) external {
// Limit the number of each signature type to 25
uint256 numEoaSigs = bound(_split.numEoaSigs, 1, 25);
uint256 numEthSignSigs = bound(_split.numEthSignSigs, 1, 25);
// uint256 numContractSigs = bound(_split.numContractSigs, 1, 25);
// uint256 numApprovedHashSigs = bound(_split.numApprovedHashSigs, 1, 25);
// uint256 numSigs = numEoaSigs + numApprovedHashSigs + numContractSigs + numEthSignSigs;
uint256 numSigs = numEoaSigs + numEthSignSigs;
uint256 numSigs = bound(_numSigs, 1, 25);
(, uint256[] memory keys) = makeAddrsAndKeys(numSigs);
// record the signature types for each key
for (uint256 i; i < numSigs; i++) {
// Generate EOA keys for both EOA and ETH Sign signatures
if (i < numEoaSigs) {
sigTypes[keys[i]] = SigType.Eoa;
} else if (i < numEoaSigs + numEthSignSigs) {
sigTypes[keys[i]] = SigType.EthSign;
} else {
// Generate approved hash signatures
// Generate eth_sign signatures
revert("not implemented");
}
}
// Now sort the keys array. By doing this after assigning a signature type to each key,
// we ensure that the signature types are randomly ordered. It probably doesn't matter either
// way, but this is more realistic.
keys = sortPKsByComputedAddress(keys);
// Create a new safeInstance with M=N, so that it requires a signature from each key.
......@@ -69,21 +43,39 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners {
// Create an empty array of signature data
bytes memory signatures;
// Populate the signatures by iterating over the safeInstance owners list.
// is a requirement for the ordering of signatures in the Safe contract.
// Populate the signatures by iterating over the keys, and choosing the signature type based
// on the key.
uint8 v;
bytes32 r;
bytes32 s;
for (uint256 i; i < keys.length; i++) {
if (sigTypes[keys[i]] == SigType.Eoa) {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(keys[i], _digest);
if (sigType(keys[i]) == SigTypes.Eoa) {
(v, r, s) = vm.sign(keys[i], _digest);
// Safe signatures are encoded as r, s, v, not v, r, s.
signatures = bytes.concat(signatures, abi.encodePacked(r, s, v));
} else if (sigTypes[keys[i]] == SigType.EthSign) {
(uint8 v, bytes32 r, bytes32 s) =
vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest)));
} else if (sigType(keys[i]) == SigTypes.EthSign) {
(v, r, s) = vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest)));
v += 4;
signatures = bytes.concat(signatures, abi.encodePacked(r, s, v));
}
} else if (sigType(keys[i]) == SigTypes.ApprovedHash) {
vm.prank(getAddr(keys[i]));
safeInstance.safe.approveHash(_digest);
v = 1;
s; // s is not checked on approved hash signatures.
r = bytes32(uint256(uint160(getAddr(keys[i]))));
signatures = bytes.concat(signatures, abi.encodePacked(r, s, v));
} // else if (sigType(keys[i]) == SigTypes.Contract) {
// address addr = decodeSmartContractWalletAsAddress(keys[i]);
// r = bytes32(uint256(uint160(addr)));
// vm.mockCall(
// addr, abi.encodeWithSignature("isValidSignature(bytes,bytes)"),
// abi.encode(EIP1271_MAGIC_VALUE)
// );
// v = 1;
// s; // s is not checked on approved hash signatures.
// signatures = bytes.concat(signatures, abi.encodePacked(r, s, v));
// }
}
// Signature checking on the Safe should succeed.
// temp note: the second arg is the data, which is only used in the contract signatures type.
safeInstance.safe.checkNSignatures(_digest, hex"", signatures, numSigs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment