Skip to content

Commit

Permalink
~~
Browse files Browse the repository at this point in the history
  • Loading branch information
z0r0z committed Aug 17, 2023
1 parent ccdf77b commit ddc1dee
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 27 deletions.
48 changes: 33 additions & 15 deletions src/Keep.sol
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ contract Keep is ERC1155TokenReceiver, KeepToken, Multicallable {
signer = signers[i];

// Prevent zero and duplicate signers.
if (previous >= signer) revert InvalidSig();
if (previous >= signer) revert Unauthorized();

previous = signer;

Expand Down Expand Up @@ -307,13 +307,13 @@ contract Keep is ERC1155TokenReceiver, KeepToken, Multicallable {

// Check SIGN_KEY balance.
// This also confirms non-zero `user`.
if (balanceOf[user][SIGN_KEY] == 0) revert InvalidSig();
if (balanceOf[user][SIGN_KEY] == 0) revert Unauthorized();

// Check signature recovery.
_recoverSig(hash, user, sig.v, sig.r, sig.s);

// Check against duplicates.
if (previous >= user) revert InvalidSig();
if (previous >= user) revert Unauthorized();

// Memo signature for next iteration until quorum.
previous = user;
Expand Down Expand Up @@ -450,26 +450,44 @@ contract Keep is ERC1155TokenReceiver, KeepToken, Multicallable {
if (msg.sender != entryPoint) revert Unauthorized();

if (quorum == 1) {
bytes memory userOpSignature = userOp.signature;
bytes memory signature = userOp.signature;
address signer;
bytes32 hash;
bytes32 r;
bytes32 s;
uint8 v;

/// @solidity memory-safe-assembly
assembly {
r := mload(add(userOpSignature, 0x20))
s := mload(add(userOpSignature, 0x40))
v := byte(0, mload(add(userOpSignature, 0x60)))

mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash.
mstore(0x1c, userOpHash) // 0x1c (28) is the length of the prefix.
hash := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20).
mstore(0x20, userOpHash) // Store into scratch space for keccak256.
mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes.
hash := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`.

let m := mload(0x40) // Cache the free memory pointer.
let signatureLength := mload(signature)
mstore(0x00, hash)
mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.
mstore(0x40, mload(add(signature, 0x20))) // `r`.
mstore(0x60, mload(add(signature, 0x40))) // `s`.
signer := mload(
staticcall(
gas(), // Amount of gas left for the transaction.
eq(signatureLength, 65), // Address of `ecrecover`.
0x00, // Start of input.
0x80, // Size of input.
0x01, // Start of output.
0x20 // Size of output.
)
)
// `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f) // `InvalidSignature()`.
revert(0x1c, 0x04)
}
mstore(0x60, 0) // Restore the zero slot.
mstore(0x40, m) // Restore the free memory pointer.
}

// Check SIGN_KEY balance.
// This also confirms non-zero `user`.
balanceOf[ecrecover(hash, v, r, s)][SIGN_KEY] != 0
balanceOf[signer][SIGN_KEY] != 0
? validationData = 0
: validationData = 1;
} else {
Expand Down
10 changes: 4 additions & 6 deletions src/KeepToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ abstract contract KeepToken {
/// Custom Errors
/// -----------------------------------------------------------------------

error InvalidSig();
error InvalidSignature();

error LengthMismatch();

Expand Down Expand Up @@ -214,9 +214,7 @@ abstract contract KeepToken {
)
)
) {
// Store the function selector of `InvalidSig()`.
mstore(0x00, 0xc90c66b5)
// Revert with (offset, size).
mstore(0x00, 0x8baa579f) // `InvalidSignature()`.
revert(0x1c, 0x04)
}
}
Expand Down Expand Up @@ -449,7 +447,7 @@ abstract contract KeepToken {
bytes32 r,
bytes32 s
) public payable virtual {
if (owner == address(0)) revert InvalidSig();
if (owner == address(0)) revert InvalidSignature();

if (block.timestamp > deadline) revert ExpiredSig();

Expand Down Expand Up @@ -591,7 +589,7 @@ abstract contract KeepToken {
bytes32 r,
bytes32 s
) public payable virtual {
if (delegator == address(0)) revert InvalidSig();
if (delegator == address(0)) revert InvalidSignature();

if (block.timestamp > deadline) revert ExpiredSig();

Expand Down
12 changes: 6 additions & 6 deletions test/Keep.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ contract KeepTest is Keep(address(0), address(0)), Test {
outOfOrderSigners[0] = alice > bob ? alice : bob;
outOfOrderSigners[1] = alice > bob ? bob : alice;

vm.expectRevert(InvalidSig.selector);
vm.expectRevert(InvalidSignature.selector);
factory.deployKeep(name2, calls, outOfOrderSigners, 2);
}

Expand Down Expand Up @@ -737,7 +737,7 @@ contract KeepTest is Keep(address(0), address(0)), Test {
assert(keep.nonce() == 2);

// Confirm revert for stale nonce.
vm.expectRevert(InvalidSig.selector);
vm.expectRevert(InvalidSignature.selector);
keep.execute(Operation.call, alice, 1 ether, "", sigs);
}

Expand Down Expand Up @@ -852,7 +852,7 @@ contract KeepTest is Keep(address(0), address(0)), Test {
sigs[1] = alice > charlie ? aliceSig : charlieSig;

// Execute tx.
vm.expectRevert(InvalidSig.selector);
vm.expectRevert(InvalidSignature.selector);
keep.execute(Operation.call, address(mockDai), 0, tx_data, sigs);
}

Expand Down Expand Up @@ -886,7 +886,7 @@ contract KeepTest is Keep(address(0), address(0)), Test {
sigs[1] = alice > bob ? bobSig : aliceSig;

// Execute tx.
vm.expectRevert(InvalidSig.selector);
vm.expectRevert(InvalidSignature.selector);
keep.execute(Operation.call, address(mockDai), 0, tx_data, sigs);
}

Expand All @@ -910,7 +910,7 @@ contract KeepTest is Keep(address(0), address(0)), Test {
sigs[1] = aliceSig;

// Execute tx.
vm.expectRevert(InvalidSig.selector);
vm.expectRevert(InvalidSignature.selector);
keep.execute(Operation.call, address(mockDai), 0, tx_data, sigs);
}

Expand Down Expand Up @@ -944,7 +944,7 @@ contract KeepTest is Keep(address(0), address(0)), Test {
sigs[1] = alice > nully ? aliceSig : nullSig;

// Execute tx.
vm.expectRevert(InvalidSig.selector);
vm.expectRevert(InvalidSignature.selector);
keep.execute(Operation.call, address(mockDai), 0, tx_data, sigs);
}

Expand Down

0 comments on commit ddc1dee

Please sign in to comment.