develop #5

Merged
p1r0 merged 3 commits from develop into main 2024-05-09 01:26:55 +00:00
5 changed files with 122 additions and 69 deletions
Showing only changes of commit c39a3cd90b - Show all commits

@ -1 +1 @@
Subproject commit 01ef448981be9d20ca85f2faf6ebdf591ce409f3
Subproject commit 52c36d412e8681053975396223d0ea39687fe33b

View File

@ -3,6 +3,7 @@ pragma solidity ^0.8.23;
import {Script, console2} from "forge-std/Script.sol";
import { DappIndexer} from "src/DappIndexer.sol";
import { CIDStorage } from "src/CIDStorage.sol";
contract DappIndexerScript is Script {
DappIndexer public dappIdxr;
@ -19,63 +20,41 @@ contract DappIndexerScript is Script {
uint256 deployerPrivateKey = vm.envUint("PK0");
// startBroadcast and stopBraodcast will let us execute transactions anything between them
vm.startBroadcast(deployerPrivateKey);
// here we just need to deploy a new contractc
// here we just need to deploy a new contract
dappIdxr = new DappIndexer(owner, owner);
console2.log("The Dapps Indexer contract address is: ", address(dappIdxr));
// Define a Dapp name
bytes32 dapp_name = bytes32("Dapp01");
// Define DappURI splited into two bytes32 CIDs
bytes32 CID1;
bytes32 CID2;
(CID1, CID2) = stringToBytes32Pair(dappsURI[0]);
(CID1, CID2) = CIDStorage.stringToBytes32Pair(dappsURI[0]);
// Add Dapp
console2.log("-----Adding Dapp-----");
console2.log("Dapp Name is:");
console2.logBytes32(bytes32("Dapp01"));
console2.logBytes32(dapp_name);
console2.log("Bytes32 first:");
console2.logBytes32(CID1);
console2.log("Bytes32 second:");
console2.logBytes32(CID2);
console2.log(Bytes32PairToString(CID1, CID2));
dappIdxr.addDapp(bytes32("Dapp01"), DappIndexer.PackedCID(CID1, CID2));
console2.log(CIDStorage.bytes32PairToString(CID1, CID2));
dappIdxr.addDapp(dapp_name, DappIndexer.PackedCID(CID1, CID2));
// retrive Dapp
console2.log("-----retriving Dapp-----");
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(bytes32("Dapp01"));
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(dapp_name);
console2.log("Bytes32 first:");
console2.logBytes32(dapp1.CID1);
console2.log("Bytes32 second:");
console2.logBytes32(dapp1.CID2);
console2.log(Bytes32PairToString(dapp1.CID1, dapp1.CID2));
// reconstruct the CID and verify
console2.log(CIDStorage.bytes32PairToString(dapp1.CID1, dapp1.CID2));
vm.stopBroadcast();
}
function Bytes32PairToString(bytes32 part1, bytes32 part2) public pure returns (string memory) {
// Concatenate the two bytes32 variables
bytes memory concatenatedBytes = abi.encodePacked(part1, part2);
// Truncate the concatenated bytes to 59 bytes
bytes memory truncatedBytes = new bytes(59);
for (uint i = 0; i < 59; i++) {
truncatedBytes[i] = concatenatedBytes[i];
}
// Convert the truncated bytes to a string
string memory str = string(truncatedBytes);
return str;
}
function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
bytes memory sourceBytes = bytes(source);
require(sourceBytes.length == 59, "URI string must equal to 59 bytes");
assembly {
// Load the first 32 bytes of the string data
part1 := mload(add(sourceBytes, 32))
// Load the second 32 bytes of the string data
part2 := mload(add(sourceBytes, 64))
}
}
}

32
src/CIDStorage.sol Normal file
View File

@ -0,0 +1,32 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
library CIDStorage {
function bytes32PairToString(bytes32 part1, bytes32 part2) public pure returns (string memory) {
// Concatenate the two bytes32 variables
bytes memory concatenatedBytes = abi.encodePacked(part1, part2);
// Truncate the concatenated bytes to 59 bytes
bytes memory truncatedBytes = new bytes(59);
for (uint i = 0; i < 59; i++) {
truncatedBytes[i] = concatenatedBytes[i];
}
// Convert the truncated bytes to a string
string memory str = string(truncatedBytes);
return str;
}
function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
bytes memory sourceBytes = bytes(source);
require(sourceBytes.length == 59, "URI string must equal to 59 bytes");
assembly {
// Load the first 32 bytes of the string data
part1 := mload(add(sourceBytes, 32))
// Load the second 32 bytes of the string data
part2 := mload(add(sourceBytes, 64))
}
}
}

View File

@ -14,6 +14,8 @@ contract DappIndexer is AccessControl {
mapping (bytes32 => PackedCID) private dapps;
bytes32[] public dapp_names;
constructor(
address defaultAdmin,
address moderator
@ -24,14 +26,49 @@ contract DappIndexer is AccessControl {
function addDapp(bytes32 dapp_name, PackedCID calldata cid)
external onlyRole(MODERATOR_ROLE) {
//if the struct does not exists trace it on the array
if (dapps[dapp_name].CID1 != 0 && dapps[dapp_name].CID2 != 0) {
dapp_names.push(dapp_name);
}
dapps[dapp_name] = PackedCID(cid.CID1, cid.CID2);
}
function removeDapp(bytes32 dapp_name) external onlyRole(MODERATOR_ROLE) {
//@Notice: consider calling getDappIndex internal and pop dapps and dapp_names
//@Notice: Yet requiring index might give extra verification
function removeDapp(uint index, bytes32 dapp_name)
external onlyRole(MODERATOR_ROLE) {
require(index < dapp_names.length, "dapp index out of bounds");
require(dapp_names[index] == dapp_name);
dapp_names[index] = dapp_names[dapp_names.length - 1];
dapp_names.pop();
delete dapps[dapp_name];
}
function getDapp(bytes32 dapp_name) external view returns (PackedCID memory){
return dapps[dapp_name];
}
function getDappIndex(bytes32 dapp_name) external view returns (uint256 i) {
require(dappExists(dapp_name));
for(i; i <= dapp_names.length; i++){
if(dapp_names[i] == dapp_name){
return i;
}
}
}
function listDappNames() external view returns (bytes32[] memory) {
return dapp_names;
}
function dappExists(bytes32 dapp_name) public view returns (bool) {
for(uint i; i <= dapp_names.length; i++){
if(dapp_names[i] == dapp_name){
return true;
}
}
return false;
}
}

View File

@ -3,64 +3,69 @@ pragma solidity ^0.8.23;
import { Test, console2 } from "forge-std/Test.sol";
import { DappIndexer } from "src/DappIndexer.sol";
import { CIDStorage } from "src/CIDStorage.sol";
contract DappIndexerTest is Test {
DappIndexer public dappIdxr;
string[] public dappsURI;
address public owner;
function setUp() public {
dappIdxr = new DappIndexer(address(this), address(this));
dappsURI = vm.envString("dapps", ' ');
owner = vm.envAddress("ACC0");
}
// Test adding a dapp that doesn't exist
function testAddDapp() public {
bytes32 dapp_name = bytes32("Dapp01");
bytes32 CID1;
bytes32 CID2;
(CID1, CID2) = stringToBytes32Pair(dappsURI[0]);
(CID1, CID2) = CIDStorage.stringToBytes32Pair(dappsURI[0]);
// Add Dapp
console2.log("Dapp Name is:");
console2.logBytes32(bytes32("Dapp01"));
console2.logBytes32(dapp_name);
console2.log("Bytes32 first:");
console2.logBytes32(CID1);
console2.log("Bytes32 second:");
console2.logBytes32(CID2);
console2.log(Bytes32PairToString(CID1, CID2));
dappIdxr.addDapp(bytes32("Dapp01"), DappIndexer.PackedCID(CID1, CID2));
console2.log(CIDStorage.bytes32PairToString(CID1, CID2));
dappIdxr.addDapp(dapp_name, DappIndexer.PackedCID(CID1, CID2));
// retrive Dapp
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(bytes32("Dapp01"));
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(dapp_name);
assertEq(CID1, dapp1.CID1);
assertEq(CID2, dapp1.CID2);
string memory retrivedDappURI = Bytes32PairToString(dapp1.CID1, dapp1.CID2);
// reconstruct the CID and verify
string memory retrivedDappURI = CIDStorage.bytes32PairToString(dapp1.CID1, dapp1.CID2);
assertEq(dappsURI[0], retrivedDappURI);
}
function Bytes32PairToString(bytes32 part1, bytes32 part2) public pure returns (string memory) {
// Concatenate the two bytes32 variables
bytes memory concatenatedBytes = abi.encodePacked(part1, part2);
//## ToDo ISSUE #2
//
//### Features testing
//
//- [x] test adding a dapp and retrive it. (addDapp, getDapp)
//
//- [ ] test removing a dapp that exists (verify dapps and dapp_names)
//- [ ] test dappExists (lower, upper, fuzz)
//- [ ] test removing a dapp that doesn't exist
//- [ ] test getting that names (listDappNames)
//- [ ] test getDappIndex (lower, upper, fuzz)
//- [ ] check if dapp name exists
//
//### Library testing
//
//- [ ] test adding longer CID
//- [ ] test adding shorter CID
//- [ ] test fuzz
//
//### Testing Roles Open Zeppelin Module
//
//- [ ] test roles for educational purposes.
//
// Truncate the concatenated bytes to 59 bytes
bytes memory truncatedBytes = new bytes(59);
for (uint i = 0; i < 59; i++) {
truncatedBytes[i] = concatenatedBytes[i];
}
// Convert the truncated bytes to a string
string memory str = string(truncatedBytes);
return str;
}
function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
bytes memory sourceBytes = bytes(source);
require(sourceBytes.length == 59, "URI string must equal to 59 bytes");
assembly {
// Load the first 32 bytes of the string data
part1 := mload(add(sourceBytes, 32))
// Load the second 32 bytes of the string data
part2 := mload(add(sourceBytes, 64))
}
}
}