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"; ...@@ -9,21 +9,19 @@ import "test/safe-tools/SafeTestTools.sol";
import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol";
contract GetSigners_Test is Test, SafeTestTools, GetSigners { contract GetSigners_Test is Test, SafeTestTools, GetSigners {
struct SigTypeCount { bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;
uint256 numEoaSigs;
uint256 numEthSignSigs;
uint256 numApprovedHashSigs;
uint256 numContractSigs;
}
enum SigType { enum SigTypes {
Eoa, Eoa,
EthSign, EthSign,
ApprovedHash, ApprovedHash //,
Contract // 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: /// @dev Test that for a given set of signatures:
/// 1. safe.checkNSignatures() succeeds /// 1. safe.checkNSignatures() succeeds
...@@ -32,35 +30,11 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners { ...@@ -32,35 +30,11 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners {
/// Demonstrating these three properties is sufficient to prove that the getSigners() method /// Demonstrating these three properties is sufficient to prove that the getSigners() method
/// returns the same signatures as those recovered by safe.checkNSignatures(). /// returns the same signatures as those recovered by safe.checkNSignatures().
/// todo(maurelian): include tests for EIP1271 signatures, and contract signatures. /// 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 // Limit the number of each signature type to 25
uint256 numEoaSigs = bound(_split.numEoaSigs, 1, 25); uint256 numSigs = bound(_numSigs, 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[] memory keys) = makeAddrsAndKeys(numSigs); (, 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); keys = sortPKsByComputedAddress(keys);
// Create a new safeInstance with M=N, so that it requires a signature from each key. // 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 { ...@@ -69,21 +43,39 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners {
// Create an empty array of signature data // Create an empty array of signature data
bytes memory signatures; bytes memory signatures;
// Populate the signatures by iterating over the safeInstance owners list. // Populate the signatures by iterating over the keys, and choosing the signature type based
// is a requirement for the ordering of signatures in the Safe contract. // on the key.
uint8 v;
bytes32 r;
bytes32 s;
for (uint256 i; i < keys.length; i++) { for (uint256 i; i < keys.length; i++) {
if (sigTypes[keys[i]] == SigType.Eoa) { if (sigType(keys[i]) == SigTypes.Eoa) {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(keys[i], _digest); (v, r, s) = vm.sign(keys[i], _digest);
// Safe signatures are encoded as r, s, v, not v, r, s. // Safe signatures are encoded as r, s, v, not v, r, s.
signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); signatures = bytes.concat(signatures, abi.encodePacked(r, s, v));
} else if (sigTypes[keys[i]] == SigType.EthSign) { } else if (sigType(keys[i]) == SigTypes.EthSign) {
(uint8 v, bytes32 r, bytes32 s) = (v, r, s) = vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest)));
vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest)));
v += 4; v += 4;
signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); 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. // Signature checking on the Safe should succeed.
// temp note: the second arg is the data, which is only used in the contract signatures type. // temp note: the second arg is the data, which is only used in the contract signatures type.
safeInstance.safe.checkNSignatures(_digest, hex"", signatures, numSigs); 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