Skip to content

Commit

Permalink
Update and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-kaufman committed Sep 13, 2023
1 parent 4fbce8b commit 0898be7
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 73 deletions.
13 changes: 4 additions & 9 deletions metamask_signer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@
{ name: "auditor", type: "Auditor" },
{ name: "issuedAt", type: "uint256" },
{ name: "ercs", type: "uint256[]" },
{ name: "contractData", type: "Contract" },
{ name: "chainId", type: "uint256" },
{ name: "contractAddress", type: "address" },
{ name: "auditHash", type: "bytes32" },
{ name: "auditUri", type: "string" }
],
Expand All @@ -251,10 +252,6 @@
{ name: "uri", type: "string" },
{ name: "authors", type: "string[]" }
],
Contract: [
{ name: "chainId", type: "uint256" },
{ name: "contractAddress", type: "address" }
]
};


Expand All @@ -280,10 +277,8 @@
},
issuedAt: Date.now(),
ercs: Array.from(document.querySelectorAll('.erc-input')).map(input => parseInt(input.value)),
contract: {
chainId: parseInt(document.getElementById('chainId').value), // Assuming Ethereum Mainnet. Change this if you're using a different network.
address: document.getElementById('contractAddress').value
},
chainId: parseInt(document.getElementById('chainId').value), // Assuming Ethereum Mainnet. Change this if you're using a different network.
contractAddress: document.getElementById('contractAddress').value,
auditHash: await computePdfHash(),
auditUri: document.getElementById('auditUri').value
}
Expand Down
12 changes: 0 additions & 12 deletions onchain_audit_registry/script/Counter.s.sol

This file was deleted.

26 changes: 7 additions & 19 deletions onchain_audit_registry/src/AuditRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,27 @@ contract AuditRegistry is Ownable, EIP712 {
error BadSignatureVersion();

bytes32 public constant AUDIT_SUMMARY_TYPEHASH =
keccak256("AuditSummary(Auditor auditor,uint256 issuedAt,uint256[] ercs,Contract contractData,bytes32 auditHash,string auditUri)");
keccak256("AuditSummary(Auditor auditor,uint256 issuedAt,uint256[] ercs,uint256 chainId,address contractAddress,bytes32 auditHash,string auditUri)");
bytes32 public constant AUDITOR_TYPEHASH = keccak256("Auditor(string name,string uri,string[] authors)");
bytes32 public constant CONTRACT_TYPEHASH = keccak256("Contract(uint256 chainId,address contractAddress)");

struct Auditor {
string name;
string uri;
string[] authors;
}

struct Contract {
bytes32 chainId;
address contractAddress;
}

struct AuditSummary {
Auditor auditor;
uint256 issuedAt;
uint256[] ercs;
Contract contractData;
uint256 chainId;
address contractAddress;
bytes32 auditHash;
string auditUri;
}

string public constant NAME = "Audit Registry";
string public constant VERSION = "1";
string public constant NAME = "ERC-7652: Onchain Audit Representation";
string public constant VERSION = "1.0";

mapping(address => bool) public auditorsWhitelist;

Expand Down Expand Up @@ -82,7 +77,8 @@ contract AuditRegistry is Ownable, EIP712 {
_hashAuditor(_auditSummary.auditor),
_auditSummary.issuedAt,
keccak256(abi.encodePacked(_auditSummary.ercs)),
_hashContract(_auditSummary.contractData),
_auditSummary.chainId,
_auditSummary.contractAddress,
_auditSummary.auditHash,
keccak256(bytes(_auditSummary.auditUri))
));
Expand All @@ -103,14 +99,6 @@ contract AuditRegistry is Ownable, EIP712 {
));
}

function _hashContract(Contract calldata _contract) internal pure returns (bytes32) {
return keccak256(abi.encode(
CONTRACT_TYPEHASH,
_contract.chainId,
_contract.contractAddress
));
}

function _recover(
bytes32 hash,
bytes memory signature
Expand Down
147 changes: 147 additions & 0 deletions onchain_audit_registry/test/AuditRegistry.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Test} from "forge-std/Test.sol";
import {AuditRegistry} from "../src/AuditRegistry.sol";
import {ECDSA} from "openzeppelin/utils/cryptography/ECDSA.sol";

contract CounterTest is Test {
AuditRegistry public auditRegistry;
address public addr1 = vm.addr(1);
address public addr2 = vm.addr(2);
address public addr3 = vm.addr(3);
AuditRegistry.AuditSummary auditSummary;

function setUp() public {
auditRegistry = new AuditRegistry(addr1);
address[] memory addrs = new address[](1);
addrs[0] = addr1;
bool[] memory isWhitelisted = new bool[](1);
isWhitelisted[0] = true;
vm.prank(addr1);
auditRegistry.updateAuditorsWhitelist(addrs, isWhitelisted);

string[] memory authors = new string[](2);
authors[0] = "author1";
authors[1] = "author2";

uint256[] memory ercs = new uint256[](2);
ercs[0] = 123;
ercs[1] = 456;

auditSummary = AuditRegistry.AuditSummary({
auditor: AuditRegistry.Auditor({
name: "Name",
uri: "URI",
authors: authors
}),
issuedAt: 100,
ercs: ercs,
chainId: 1,
contractAddress: address(this),
auditHash: "auditHash",
auditUri: "auditUri"
});
}

function testUpdateAuditorsWhitelist() public {
address[] memory addrs = new address[](2);
addrs[0] = addr1;
addrs[1] = addr2;
bool[] memory isWhitelisted = new bool[](2);
isWhitelisted[0] = false;
isWhitelisted[1] = true;
vm.prank(addr1);
auditRegistry.updateAuditorsWhitelist(addrs, isWhitelisted);
assertFalse(auditRegistry.auditorsWhitelist(addr1));
assertTrue(auditRegistry.auditorsWhitelist(addr2));
isWhitelisted[0] = true;
isWhitelisted[1] = false;
vm.prank(addr1);
auditRegistry.updateAuditorsWhitelist(addrs, isWhitelisted);
assertTrue(auditRegistry.auditorsWhitelist(addr1));
assertFalse(auditRegistry.auditorsWhitelist(addr2));

bool[] memory isWhitelistedWrongLength = new bool[](3);
isWhitelistedWrongLength[0] = true;
isWhitelistedWrongLength[1] = false;
isWhitelistedWrongLength[2] = false;

vm.expectRevert(abi.encodeWithSignature("ArraysLengthMismatched()"));
vm.prank(addr1);
auditRegistry.updateAuditorsWhitelist(addrs, isWhitelistedWrongLength);

vm.expectRevert("Ownable: caller is not the owner");
vm.prank(addr2);
auditRegistry.updateAuditorsWhitelist(addrs, isWhitelisted);
}

function testVerifyAuditSummaryBadSignatureLength() public {
vm.expectRevert(abi.encodeWithSignature("BadSignatureLength()"));
auditRegistry.verifyAuditSummary(auditSummary, "badLength");
}

function testVerifyAuditSummaryBadSignatureVersion() public {
bytes32 txHash = _getTxHash(auditSummary);
(, bytes32 r, bytes32 s) = vm.sign(1, txHash);
uint8 v = 3;
bytes memory sig = abi.encodePacked(r, s, v);

vm.expectRevert(abi.encodeWithSignature("BadSignatureVersion()"));
auditRegistry.verifyAuditSummary(auditSummary, sig);
}

function testVerifyAuditSummarySignature() public {
bytes32 txHash = _getTxHash(auditSummary);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(1, txHash);
bytes memory sig = abi.encodePacked(r, s, v);

assertTrue(auditRegistry.verifyAuditSummary(auditSummary, sig));

(uint8 v2, bytes32 r2, bytes32 s2) = vm.sign(2, txHash);
bytes memory badSig = abi.encodePacked(r2, s2, v2);

assertFalse(auditRegistry.verifyAuditSummary(auditSummary, badSig));
}

function testVerifyAuditSummaryRSV() public {
bytes32 txHash = _getTxHash(auditSummary);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(1, txHash);

assertTrue(auditRegistry.verifyAuditSummary(auditSummary, r, s, v));

(uint8 v2, bytes32 r2, bytes32 s2) = vm.sign(2, txHash);

assertFalse(auditRegistry.verifyAuditSummary(auditSummary, r2, s2, v2));
}

function _getTxHash(AuditRegistry.AuditSummary memory _auditSummary) internal view returns (bytes32) {
bytes32 structHash = keccak256(abi.encode(
auditRegistry.AUDIT_SUMMARY_TYPEHASH(),
_hashAuditor(_auditSummary.auditor),
_auditSummary.issuedAt,
keccak256(abi.encodePacked(_auditSummary.ercs)),
_auditSummary.chainId,
_auditSummary.contractAddress,
_auditSummary.auditHash,
keccak256(bytes(_auditSummary.auditUri))
));

return ECDSA.toTypedDataHash(auditRegistry.DOMAIN_SEPARATOR(), structHash);
}

function _hashAuditor(AuditRegistry.Auditor memory _auditor) internal view returns (bytes32) {
bytes32[] memory authors = new bytes32[](_auditor.authors.length);
for (uint256 i = 0; i < _auditor.authors.length; ++i) {
authors[i] = keccak256(bytes(_auditor.authors[i]));
}
return keccak256(abi.encode(
auditRegistry.AUDITOR_TYPEHASH(),
keccak256(bytes(_auditor.name)),
keccak256(bytes(_auditor.uri)),
keccak256(abi.encodePacked(authors))
));
}


}
24 changes: 0 additions & 24 deletions onchain_audit_registry/test/Counter.t.sol

This file was deleted.

13 changes: 4 additions & 9 deletions simple_signer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const types: any = {
{ name: "auditor", type: "Auditor" },
{ name: "issuedAt", type: "uint256" },
{ name: "ercs", type: "uint256[]" },
{ name: "contractData", type: "Contract" },
{ name: "chainId", type: "uint256" },
{ name: "contractAddress", type: "address" },
{ name: "auditHash", type: "bytes32" },
{ name: "auditUri", type: "string" }
],
Expand All @@ -30,10 +31,6 @@ const types: any = {
{ name: "uri", type: "string" },
{ name: "authors", type: "string[]" }
],
Contract: [
{ name: "chainId", type: "uint256" },
{ name: "contractAddress", type: "address" }
]
};

// Convert chain ID to bytes32 format
Expand All @@ -51,10 +48,8 @@ const auditSummaryData = {
},
issuedAt: Date.now(),
ercs: [20, 721],
contract: {
chainId: 1,
address: "0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e"
},
chainId: 1,
contractAddress: "0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e",
auditHash: toBytes32(23),
auditUri: "https://auditwebsite.com/report"
};
Expand Down

0 comments on commit 0898be7

Please sign in to comment.