Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
akarys92 committed Jul 19, 2024
1 parent 46e5d58 commit 034d8a1
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 50 deletions.
25 changes: 13 additions & 12 deletions script/Counter.s.sol
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
// SPDX-License-Identifier: UNLICENSED
// // SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Script, console} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";

contract CounterScript is Script {
Counter public counter;
// import {Script, console} from "forge-std/Script.sol";
// import {Counter} from "../src/Counter.sol";

function setUp() public {}
// contract CounterScript is Script {
// Counter public counter;

function run() public {
vm.startBroadcast();
// function setUp() public {}

counter = new Counter();
// function run() public {
// vm.startBroadcast();

vm.stopBroadcast();
}
}
// counter = new Counter();

// vm.stopBroadcast();
// }
// }
14 changes: 0 additions & 14 deletions src/Counter.sol

This file was deleted.

102 changes: 102 additions & 0 deletions src/HookRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
pragma solidity ^0.8.10;

import "solmate/tokens/ERC721.sol";
import "forge-std/console.sol";

contract HookRegistry is ERC721 {
uint256 private _tokenIdCounter;

struct HookMetadata {
address hookAddress;
string ipfsMetadataHash;
address[] auditors;
}

mapping(uint256 => HookMetadata) public hookMetadata;
mapping(uint256 => address) private hookOwners;

event HookMinted(uint256 tokenId, address owner, string ipfsMetadataHash);
event MetadataUpdated(uint256 tokenId, string newIpfsMetadataHash);
event AuditorAdded(uint256 tokenId, address auditor);

constructor() ERC721("HookRegistry", "HOOK") {}

modifier onlyHookOwner(uint256 tokenId) {
require(msg.sender == hookOwners[tokenId], "Not the owner");
_;
}

function mintHookNFT(
address hookAddress,
string memory ipfsMetadataHash
) external {
require(isContractDeployer(msg.sender, hookAddress), "Not the deployer of the hook");

uint256 tokenId = _tokenIdCounter++;
_mint(msg.sender, tokenId);
hookOwners[tokenId] = msg.sender;

hookMetadata[tokenId] = HookMetadata({
hookAddress: hookAddress,
ipfsMetadataHash: ipfsMetadataHash,
auditors: new address[](0)
});

emit HookMinted(tokenId, msg.sender, ipfsMetadataHash);
}

function updateMetadataLink(uint256 tokenId, string memory newIpfsMetadataHash) external onlyHookOwner(tokenId) {
hookMetadata[tokenId].ipfsMetadataHash = newIpfsMetadataHash;
emit MetadataUpdated(tokenId, newIpfsMetadataHash);
}

function signAudit(uint256 tokenId) external {
HookMetadata storage metadata = hookMetadata[tokenId];
metadata.auditors.push(msg.sender);
emit AuditorAdded(tokenId, msg.sender);
}

function isAuditedBy(uint256 tokenId, address auditor) external view returns (bool) {
HookMetadata storage metadata = hookMetadata[tokenId];
for (uint256 i = 0; i < metadata.auditors.length; i++) {
if (metadata.auditors[i] == auditor) {
return true;
}
}
return false;
}

function tokenURI(uint256 tokenId) public view override returns (string memory) {
HookMetadata storage metadata = hookMetadata[tokenId];
return string(abi.encodePacked("ipfs://", metadata.ipfsMetadataHash));
}

function isContractDeployer(address deployer, address contractAddress) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(contractAddress) }

if (size == 0) {
// Contract doesn't exist, cannot verify deployer
revert("Contract doesn't exist");
// return false;
}
bytes memory code;
assembly {
code := mload(0x40)
mstore(0x40, add(code, size))
extcodecopy(contractAddress, add(code, 0x20), 0, size)
}
// bytes32 codeHash = keccak256(code);

// Recreate the address based on deployer and nonce
address expectedAddress;
bytes32 dataHash = keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)));
assembly {
mstore(0x0, dataHash)
expectedAddress := mload(0x0)
}
console.log(expectedAddress);

return expectedAddress == contractAddress;
}
}
24 changes: 0 additions & 24 deletions test/Counter.t.sol

This file was deleted.

87 changes: 87 additions & 0 deletions test/HookRegistry.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Test, console} from "forge-std/Test.sol";
import {HookRegistry} from "../src/HookRegistry.sol";

contract MockHook {
constructor() {}
}

contract HookRegistryTest is Test {
HookRegistry public hookRegistry;
MockHook public mockHook;
address public deployer;
address public otherUser;

function setUp() public {
deployer = address(this);
otherUser = address(0x2);

hookRegistry = new HookRegistry();
mockHook = new MockHook();
}

function testMintHookNFT() public {
string memory ipfsMetadataHash = "QmSomeHash";

hookRegistry.mintHookNFT(address(mockHook), ipfsMetadataHash);

uint256 tokenId = 0;
string memory tokenURI = hookRegistry.tokenURI(tokenId);
assertEq(tokenURI, string(abi.encodePacked("ipfs://", ipfsMetadataHash)));
}

function testMintHookNFT_NotDeployer() public {
string memory ipfsMetadataHash = "QmSomeHash";

vm.prank(otherUser);
vm.expectRevert("Not the deployer of the hook");
hookRegistry.mintHookNFT(address(mockHook), ipfsMetadataHash);
}

function testUpdateMetadataLink() public {
string memory ipfsMetadataHash = "QmSomeHash";

hookRegistry.mintHookNFT(address(mockHook), ipfsMetadataHash);

string memory newIpfsMetadataHash = "QmNewHash";
hookRegistry.updateMetadataLink(0, newIpfsMetadataHash);

uint256 tokenId = 0;
string memory tokenURI = hookRegistry.tokenURI(tokenId);
assertEq(tokenURI, string(abi.encodePacked("ipfs://", newIpfsMetadataHash)));
}

function testUpdateMetadataLink_NotOwner() public {
string memory ipfsMetadataHash = "QmSomeHash";

hookRegistry.mintHookNFT(address(mockHook), ipfsMetadataHash);

vm.prank(otherUser);
vm.expectRevert("Not the owner");
hookRegistry.updateMetadataLink(0, "QmNewHash");
}

function testSignAudit() public {
string memory ipfsMetadataHash = "QmSomeHash";

hookRegistry.mintHookNFT(address(mockHook), ipfsMetadataHash);

vm.prank(otherUser);
hookRegistry.signAudit(0);

bool isAudited = hookRegistry.isAuditedBy(0, otherUser);
assertTrue(isAudited);
}

function testTokenURI() public {
string memory ipfsMetadataHash = "QmSomeHash";

hookRegistry.mintHookNFT(address(mockHook), ipfsMetadataHash);

uint256 tokenId = 0;
string memory tokenURI = hookRegistry.tokenURI(tokenId);
assertEq(tokenURI, string(abi.encodePacked("ipfs://", ipfsMetadataHash)));
}
}

0 comments on commit 034d8a1

Please sign in to comment.