Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ hash:
forge script script/HashData.sol

sign\:%: hash
forge script script/CheckNoSignature.sol
cast wallet sign --$* $$(cat data/hashData.txt) 1>> data/signatures.txt
@echo "\033[0;32mTx signature successfully appended to data/signatures.txt"

Expand Down
14 changes: 14 additions & 0 deletions script/CheckNoSignature.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./SignatureScript.sol";

contract CheckNoSignature is SignatureScript {
function run() public {
SafeTxData memory txData = loadSafeTxData();

loadSignatures(hashData(txData));

require(signatureOf[SENDER].length == 0, "Already signed!");
}
}
57 changes: 10 additions & 47 deletions script/ExecTransaction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@ pragma solidity ^0.8.0;

import {QuickSort} from "./libraries/QuickSort.sol";

import {SafeTxDataBuilder, SafeTx, Enum} from "./SafeTxDataBuilder.sol";
import "./SignatureScript.sol";

contract ExecTransaction is SafeTxDataBuilder {
contract ExecTransaction is SignatureScript {
using QuickSort for address[];

address[] signers;
bytes[] signatures;
mapping(address => bytes) signatureOf;

function run() public {
SafeTx memory safeTx;
safeTx.data = loadSafeTxData();

loadSignatures(hashData(safeTx.data));

uint256 nbSignatures = signatures.length;
require(
nbSignatures >= THRESHOLD,
string.concat(
"Not enough signatures (found: ", vm.toString(nbSignatures), "; expected: ", vm.toString(THRESHOLD), ")"
)
);

signers.sort();

for (uint256 i; i < signers.length; ++i) {
Expand All @@ -39,45 +43,4 @@ contract ExecTransaction is SafeTxDataBuilder {
safeTx.signatures
);
}

function loadSignatures(bytes32 dataHash) internal {
bytes memory line = bytes(vm.readLine(SIGNATURES_FILE));

while (line.length > 0 && signatures.length < THRESHOLD) {
parseSignature(dataHash, line);

line = bytes(vm.readLine(SIGNATURES_FILE));
}

uint256 nbSignatures = signatures.length;
require(
nbSignatures >= THRESHOLD,
string.concat(
"Not enough signatures (found: ", vm.toString(nbSignatures), "; expected: ", vm.toString(THRESHOLD), ")"
)
);
}

function parseSignature(bytes32 dataHash, bytes memory line) internal {
require(
line.length == 132,
string.concat(
"Malformed signature: ", string(line), " (length: ", vm.toString(line.length), "; expected: 132)"
)
);

bytes memory hexSignature = new bytes(130);
for (uint256 j; j < 130; ++j) {
hexSignature[j] = line[j + 2];
}

bytes memory signature = vm.parseBytes(string(hexSignature));

(address signer, bytes32 r, bytes32 s, uint8 v) = decode(dataHash, signature);
require(signatureOf[signer].length == 0, string.concat("Duplicate signature: ", string(line)));

signatureOf[signer] = abi.encodePacked(r, s, v + 4);
signatures.push(signature);
signers.push(signer);
}
}
8 changes: 3 additions & 5 deletions script/HashData.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {SafeTxDataBuilder, SafeTxData} from "./SafeTxDataBuilder.sol";
import "./SafeTxScript.sol";

contract HashData is SafeTxDataBuilder {
contract HashData is SafeTxScript {
function run() public {
SafeTxData memory txData = loadSafeTxData();

bytes32 dataHash = hashData(txData);

vm.writeFile(HASH_DATA_FILE, vm.toString(dataHash));
vm.writeFile(HASH_DATA_FILE, vm.toString(hashData(txData)));
}
}
2 changes: 1 addition & 1 deletion script/SafeTxDataBuilder.sol → script/SafeTxScript.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct SafeTx {
bytes signatures;
}

contract SafeTxDataBuilder is Script, SignatureDecoder {
contract SafeTxScript is Script, SignatureDecoder {
using stdJson for string;

string internal ROOT = vm.projectRoot();
Expand Down
43 changes: 43 additions & 0 deletions script/SignatureScript.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./SafeTxScript.sol";

contract SignatureScript is SafeTxScript {
address[] signers;
bytes[] signatures;
mapping(address => bytes) signatureOf;

function loadSignatures(bytes32 dataHash) internal {
bytes memory line = bytes(vm.readLine(SIGNATURES_FILE));

while (line.length > 0) {
parseSignature(dataHash, line);

line = bytes(vm.readLine(SIGNATURES_FILE));
}
}

function parseSignature(bytes32 dataHash, bytes memory line) internal {
require(
line.length == 132,
string.concat(
"Malformed signature: ", string(line), " (length: ", vm.toString(line.length), "; expected: 132)"
)
);

bytes memory hexSignature = new bytes(130);
for (uint256 j; j < 130; ++j) {
hexSignature[j] = line[j + 2];
}

bytes memory signature = vm.parseBytes(string(hexSignature));

(address signer, bytes32 r, bytes32 s, uint8 v) = decode(dataHash, signature);
require(signatureOf[signer].length == 0, string.concat("Duplicate signature: ", string(line)));

signatureOf[signer] = abi.encodePacked(r, s, v + 4);
signatures.push(signature);
signers.push(signer);
}
}