From 701e0a053d934ab73e6dcc2c7005d27d499be3ae Mon Sep 17 00:00:00 2001 From: Mihajlo Pavlovic Date: Mon, 16 Dec 2024 17:13:34 +0100 Subject: [PATCH 1/3] Expand KnowledgeCollection to support paranets --- contracts/KnowledgeCollection.sol | 47 +++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/contracts/KnowledgeCollection.sol b/contracts/KnowledgeCollection.sol index 29a9a7f7..44ff1a60 100644 --- a/contracts/KnowledgeCollection.sol +++ b/contracts/KnowledgeCollection.sol @@ -8,6 +8,9 @@ import {KnowledgeCollectionStorage} from "./storage/KnowledgeCollectionStorage.s import {ShardingTableStorage} from "./storage/ShardingTableStorage.sol"; import {IdentityStorage} from "./storage/IdentityStorage.sol"; import {ParametersStorage} from "./storage/ParametersStorage.sol"; +import {ParanetKnowledgeAssetsRegistry} from "./storage/paranets/ParanetKnowledgeAssetsRegistry.sol"; +import {ParanetKnowledgeMinersRegistry} from "./storage/paranets/ParanetKnowledgeMinersRegistry.sol"; +import {ParanetsRegistry} from "./storage/paranets/ParanetsRegistry.sol"; import {KnowledgeCollectionLib} from "./libraries/KnowledgeCollectionLib.sol"; import {TokenLib} from "./libraries/TokenLib.sol"; import {IdentityLib} from "./libraries/IdentityLib.sol"; @@ -29,6 +32,9 @@ contract KnowledgeCollection is INamed, IVersioned, HubDependent { IERC20 public tokenContract; ParametersStorage public parametersStorage; IdentityStorage public identityStorage; + ParanetKnowledgeAssetsRegistry public paranetKnowledgeAssetsRegistry; + ParanetKnowledgeMinersRegistry public paranetKnowledgeMinersRegistry; + ParaneRegistry public paraneRegistry; constructor(address hubAddress) HubDependent(hubAddress) {} @@ -42,6 +48,13 @@ contract KnowledgeCollection is INamed, IVersioned, HubDependent { tokenContract = IERC20(hub.getContractAddress("Token")); parametersStorage = ParametersStorage(hub.getContractAddress("ParametersStorage")); identityStorage = IdentityStorage(hub.getContractAddress("IdentityStorage")); + paranetKnowledgeAssetsRegistry = ParanetKnowledgeAssetsRegistry( + hub.getContractAddress("ParanetKnowledgeAssetsRegistry") + ); + paranetKnowledgeMinersRegistry = ParanetKnowledgeMinersRegistry( + hub.getContractAddress("ParanetKnowledgeMinersRegistry") + ); + paranetsRegistry = ParanetsRegistry(hub.getContractAddress("ParanetsRegistry")); } function name() public pure virtual returns (string memory) { @@ -99,6 +112,7 @@ contract KnowledgeCollection is INamed, IVersioned, HubDependent { _addTokens(tokenAmount, paymaster); } + //TODO: If KC part of paranet update function updateKnowledgeCollection( uint256 id, string calldata updateOperationId, @@ -183,6 +197,22 @@ contract KnowledgeCollection is INamed, IVersioned, HubDependent { _validateTokenAmount(byteSize, epochs, tokenAmount, false); _addTokens(tokenAmount, paymaster); + + ParanetKnowledgeAssetsRegistry pkar = paranetKnowledgeAssetsRegistry; + knowledgeCollectionStorageAddress = address(kcs); + if (pkar.isParanetKnowledgeAsset(keccak256(abi.encodePacked(knowledgeCollectionStorageAddress, id)))) { + ParanetKnowledgeMinersRegistry pkmr = paranetKnowledgeMinersRegistry; + + bytes32 paranetId = pkar.getParanetId(keccak256(abi.encodePacked(knowledgeCollectionStorageAddress, id))); + + // Add Knowledge Asset Token Amount Metadata to the ParanetsRegistry + paranetsRegistry.addCumulativeKnowledgeValue(paranetId, tokenAmount); + + // Add Knowledge Asset Token Amount Metadata to the KnowledgeMinersRegistry + pkmr.addCumulativeTracSpent(msg.sender, paranetId, tokenAmount); + pkmr.addUnrewardedTracSpent(msg.sender, paranetId, tokenAmount); + pkmr.addTotalTracSpent(msg.sender, tokenAmount); + } } function increaseKnowledgeCollectionTokenAmount(uint256 id, uint96 tokenAmount, address paymaster) external { @@ -201,6 +231,23 @@ contract KnowledgeCollection is INamed, IVersioned, HubDependent { kcs.setTokenAmount(id, oldTokenAmount + tokenAmount); _addTokens(tokenAmount, paymaster); + + ParanetKnowledgeAssetsRegistry pkar = paranetKnowledgeAssetsRegistry; + knowledgeCollectionStorageAddress = address(kcs); + if (pkar.isParanetKnowledgeAsset(keccak256(abi.encodePacked(knowledgeCollectionStorageAddress, id)))) { + ParanetKnowledgeMinersRegistry pkmr = paranetKnowledgeMinersRegistry; + + bytes32 paranetId = pkar.getParanetId(keccak256(abi.encodePacked(knowledgeCollectionStorageAddress, id))); + + // Add Knowledge Asset Token Amount Metadata to the ParanetsRegistry + paranetsRegistry.addCumulativeKnowledgeValue(paranetId, tokenAmount); + + // Add Knowledge Asset Token Amount Metadata to the KnowledgeMinersRegistry + // Question is there some problem when paymaster is used ??? + pkmr.addCumulativeTracSpent(msg.sender, paranetId, tokenAmount); + pkmr.addUnrewardedTracSpent(msg.sender, paranetId, tokenAmount); + pkmr.addTotalTracSpent(msg.sender, tokenAmount); + } } function _verifySignatures( From 326fe43963fa837c83498170882e1e7dd5091ad8 Mon Sep 17 00:00:00 2001 From: Mihajlo Pavlovic Date: Mon, 16 Dec 2024 18:09:26 +0100 Subject: [PATCH 2/3] Add check owner --- contracts/paranets/Paranet.sol | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/contracts/paranets/Paranet.sol b/contracts/paranets/Paranet.sol index 884e6257..d2d7a543 100644 --- a/contracts/paranets/Paranet.sol +++ b/contracts/paranets/Paranet.sol @@ -15,6 +15,7 @@ import {IVersioned} from "../interfaces/IVersioned.sol"; import {ParanetLib} from "../libraries/ParanetLib.sol"; import {ProfileLib} from "../libraries/ProfileLib.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import {ERC1155Delta} from "../tokens/ERC1155Delta.sol"; contract Paranet is INamed, IVersioned, ContractStatus, IInitializable { event ParanetRegistered( @@ -1069,9 +1070,17 @@ contract Paranet is INamed, IVersioned, ContractStatus, IInitializable { uint256 knowledgeAssetTokenId ) internal view virtual { require(hub.isAssetStorage(knowledgeAssetStorageContract), "Given address isn't KA Storage"); - require( - IERC721(knowledgeAssetStorageContract).ownerOf(knowledgeAssetTokenId) == msg.sender, - "Caller isn't the owner of the KA" - ); + try ERC1155Delta(knowledgeAssetStorageContract).isOwnerOf(msg.sender, knowledgeAssetTokenId) returns ( + bool isOwner + ) { + require(isOwner, "Caller isn't the owner of the KA"); + // TODO: Check for each KA in KC + } catch { + try IERC721(knowledgeAssetStorageContract).ownerOf(knowledgeAssetTokenId) returns (address owner) { + require(owner == msg.sender, "Caller isn't the owner of the KA"); + } catch { + revert("Caller isn't the owner of the KA"); + } + } } } From fff3f31213291f761672776a6126a111597afdf5 Mon Sep 17 00:00:00 2001 From: Mihajlo Pavlovic Date: Mon, 16 Dec 2024 19:18:09 +0100 Subject: [PATCH 3/3] Enable submitKnowledgeAsset --- contracts/paranets/Paranet.sol | 148 +++++++++++++++++---------------- 1 file changed, 78 insertions(+), 70 deletions(-) diff --git a/contracts/paranets/Paranet.sol b/contracts/paranets/Paranet.sol index d2d7a543..d877dcf6 100644 --- a/contracts/paranets/Paranet.sol +++ b/contracts/paranets/Paranet.sol @@ -843,83 +843,91 @@ contract Paranet is INamed, IVersioned, ContractStatus, IInitializable { // return knowledgeAssetTokenId; // } - // function submitKnowledgeAsset( - // address paranetKAStorageContract, - // uint256 paranetKATokenId, - // address knowledgeAssetStorageContract, - // uint256 knowledgeAssetTokenId - // ) external onlyKnowledgeAssetOwner(knowledgeAssetStorageContract, knowledgeAssetTokenId) { - // ParanetsRegistry pr = paranetsRegistry; - // bytes32 paranetId = keccak256(abi.encodePacked(paranetKAStorageContract, paranetKATokenId)); - - // if (!pr.paranetExists(paranetId)) { - // revert ParanetLib.ParanetDoesntExist(paranetKAStorageContract, paranetKATokenId); - // } + function submitKnowledgeAsset( + address paranetKAStorageContract, + uint256 paranetKATokenId, + address knowledgeAssetStorageContract, + uint256 knowledgeAssetTokenId + ) external onlyKnowledgeAssetOwner(knowledgeAssetStorageContract, knowledgeAssetTokenId) { + ParanetsRegistry pr = paranetsRegistry; + bytes32 paranetId = keccak256(abi.encodePacked(paranetKAStorageContract, paranetKATokenId)); - // ParanetLib.MinersAccessPolicy minersAccessPolicy = pr.getMinersAccessPolicy(paranetId); + if (!pr.paranetExists(paranetId)) { + revert ParanetLib.ParanetDoesntExist(paranetKAStorageContract, paranetKATokenId); + } - // // Check if paranet is curated and if knowledge miner is whitelisted - // if ( - // minersAccessPolicy == ParanetLib.MinersAccessPolicy.CURATED && - // !pr.isKnowledgeMinerRegistered(paranetId, msg.sender) - // ) { - // revert ParanetLib.ParanetCuratedMinerDoesntExist(paranetId, msg.sender); - // } else if (minersAccessPolicy == ParanetLib.MinersAccessPolicy.OPEN) { - // // Check if Knowledge Miner has profile - // // If not: Create a profile - // if (!paranetKnowledgeMinersRegistry.knowledgeMinerExists(msg.sender)) { - // paranetKnowledgeMinersRegistry.registerKnowledgeMiner(msg.sender); - // } + ParanetLib.MinersAccessPolicy minersAccessPolicy = pr.getMinersAccessPolicy(paranetId); - // // Check if Knowledge Miner is registered on paranet - // if (!pr.isKnowledgeMinerRegistered(paranetId, msg.sender)) { - // pr.addKnowledgeMiner(paranetId, msg.sender); - // } - // } + // Check if paranet is curated and if knowledge miner is whitelisted + if ( + minersAccessPolicy == ParanetLib.MinersAccessPolicy.CURATED && + !pr.isKnowledgeMinerRegistered(paranetId, msg.sender) + ) { + revert ParanetLib.ParanetCuratedMinerDoesntExist(paranetId, msg.sender); + } else if (minersAccessPolicy == ParanetLib.MinersAccessPolicy.OPEN) { + // Check if Knowledge Miner has profile + // If not: Create a profile + if (!paranetKnowledgeMinersRegistry.knowledgeMinerExists(msg.sender)) { + paranetKnowledgeMinersRegistry.registerKnowledgeMiner(msg.sender); + } - // if ( - // paranetKnowledgeAssetsRegistry.isParanetKnowledgeAsset( - // keccak256(abi.encodePacked(knowledgeAssetStorageContract, knowledgeAssetTokenId)) - // ) - // ) { - // revert ParanetLib.KnowledgeAssetIsAPartOfOtherParanet( - // knowledgeAssetStorageContract, - // knowledgeAssetTokenId, - // paranetKnowledgeAssetsRegistry.getParanetId( - // keccak256(abi.encodePacked(knowledgeAssetStorageContract, knowledgeAssetTokenId)) - // ) - // ); - // } + // Check if Knowledge Miner is registered on paranet + if (!pr.isKnowledgeMinerRegistered(paranetId, msg.sender)) { + pr.addKnowledgeMiner(paranetId, msg.sender); + } + } - // uint96 remainingTokenAmount = serviceAgreementStorageProxy.getAgreementTokenAmount( - // hashingProxy.callHashFunction( - // HASH_FUNCTION_ID, - // abi.encodePacked( - // address(contentAssetStorage), - // knowledgeAssetTokenId, - // abi.encodePacked( - // address(contentAssetStorage), - // contentAssetStorage.getAssertionIdByIndex(knowledgeAssetTokenId, 0) - // ) - // ) - // ) - // ); + if ( + paranetKnowledgeAssetsRegistry.isParanetKnowledgeAsset( + keccak256(abi.encodePacked(knowledgeAssetStorageContract, knowledgeAssetTokenId)) + ) + ) { + revert ParanetLib.KnowledgeAssetIsAPartOfOtherParanet( + knowledgeAssetStorageContract, + knowledgeAssetTokenId, + paranetKnowledgeAssetsRegistry.getParanetId( + keccak256(abi.encodePacked(knowledgeAssetStorageContract, knowledgeAssetTokenId)) + ) + ); + } + // This needs to have separet logiic for new and old assets + uint96 remainingTokenAmount = 0; + try ERC1155Delta(knowledgeAssetStorageContract).isOwnerOf(msg.sender, knowledgeAssetTokenId) returns ( + bool isOwner + ) { + KnowledgeCollectionStorage kcs = KnowledgeCollectionStorage(knowledgeAssetStorageContract); + remainingTokenAmount = kcs.getTokenAmount(knowledgeAssetTokenId); + } catch { + remainingTokenAmount = serviceAgreementStorageProxy.getAgreementTokenAmount( + hashingProxy.callHashFunction( + HASH_FUNCTION_ID, + abi.encodePacked( + address(contentAssetStorage), + knowledgeAssetTokenId, + abi.encodePacked( + address(contentAssetStorage), + contentAssetStorage.getAssertionIdByIndex(knowledgeAssetTokenId, 0) + ) + ) + ) + ); + } - // _updateSubmittedKnowledgeAssetMetadata( - // paranetKAStorageContract, - // paranetKATokenId, - // knowledgeAssetStorageContract, - // knowledgeAssetTokenId, - // remainingTokenAmount - // ); + _updateSubmittedKnowledgeAssetMetadata( + paranetKAStorageContract, + paranetKATokenId, + knowledgeAssetStorageContract, + knowledgeAssetTokenId, + remainingTokenAmount + ); - // emit KnowledgeAssetSubmittedToParanet( - // paranetKAStorageContract, - // paranetKATokenId, - // knowledgeAssetStorageContract, - // knowledgeAssetTokenId - // ); - // } + emit KnowledgeAssetSubmittedToParanet( + paranetKAStorageContract, + paranetKATokenId, + knowledgeAssetStorageContract, + knowledgeAssetTokenId + ); + } // function processUpdatedKnowledgeAssetStatesMetadata( // address paranetKAStorageContract,