diff --git a/contracts/interfaces/modules/dispute/IDisputeModule.sol b/contracts/interfaces/modules/dispute/IDisputeModule.sol index b95850d2b..6137f35e2 100644 --- a/contracts/interfaces/modules/dispute/IDisputeModule.sol +++ b/contracts/interfaces/modules/dispute/IDisputeModule.sol @@ -156,24 +156,8 @@ interface IDisputeModule { bytes32 currentTag // The current tag of the dispute ); - /// @notice returns true if the ipId is tagged with the tag (meaning the dispute went through) - /// @param _ipId The ipId - /// @param _tag The tag - function isIpTaggedWith(address _ipId, bytes32 _tag) external view returns (bool); - /// @notice returns true if the ipId is tagged with any tag (meaning at least one dispute went through) /// @param _ipId The ipId function isIpTagged(address _ipId) external view returns (bool); - /// @notice returns the tags for a given ipId (note: this method could be expensive, use in frontends only) - /// @param _ipId The ipId - function ipTags(address _ipId) external view returns (bytes32[] memory); - - /// @notice returns the total tags for a given ipId - /// @param _ipId The ipId - function totalTagsForIp(address _ipId) external view returns (uint256); - - /// @notice returns the tag at a given index for a given ipId. No guarantees on ordering - /// @param _ipId The ipId - function tagForIpAt(address _ipId, uint256 _index) external view returns (bytes32); } diff --git a/contracts/modules/dispute-module/DisputeModule.sol b/contracts/modules/dispute-module/DisputeModule.sol index 67ae874fb..525ebdca5 100644 --- a/contracts/modules/dispute-module/DisputeModule.sol +++ b/contracts/modules/dispute-module/DisputeModule.sol @@ -56,7 +56,10 @@ contract DisputeModule is IDisputeModule, BaseModule, Governable, ReentrancyGuar /// @notice Arbitration policy for a given ipId mapping(address ipId => address arbitrationPolicy) public arbitrationPolicies; - mapping(address ipId => EnumerableSet.Bytes32Set) private _taggedIpIds; + /// @notice counter of successful disputes per ipId + /// @dev BETA feature, for mainnet tag semantics must influence effect in other modules. For now + /// any successful dispute will affect the IP protocol wide + mapping(address ipId => uint256) private successfulDisputesPerIp; /// @notice Initializes the registration module contract /// @param _controller The access controller used for IP authorization @@ -193,8 +196,7 @@ contract DisputeModule is IDisputeModule, BaseModule, Governable, ReentrancyGuar if (_decision) { disputes[_disputeId].currentTag = dispute.targetTag; - // We ignore the result of add(), we don't care if the tag is already there - _taggedIpIds[dispute.targetIpId].add(dispute.targetTag); + successfulDisputesPerIp[dispute.targetIpId]++; } else { disputes[_disputeId].currentTag = bytes32(0); } @@ -228,43 +230,17 @@ contract DisputeModule is IDisputeModule, BaseModule, Governable, ReentrancyGuar if (dispute.currentTag == IN_DISPUTE) revert Errors.DisputeModule__NotAbleToResolve(); if (msg.sender != dispute.disputeInitiator) revert Errors.DisputeModule__NotDisputeInitiator(); - // Ignore the result of remove(), resolveDispute can only be called once when there's a dispute tag. - // Once resolveDispute is called, the tag will be removed and calling this fn again will throw an error. - _taggedIpIds[dispute.targetIpId].remove(dispute.currentTag); + successfulDisputesPerIp[dispute.targetIpId]--; disputes[_disputeId].currentTag = bytes32(0); emit DisputeResolved(_disputeId); } - /// @notice returns true if the ipId is tagged with the tag (meaning the dispute went through) - /// @param _ipId The ipId - /// @param _tag The tag - function isIpTaggedWith(address _ipId, bytes32 _tag) external view returns (bool) { - return _taggedIpIds[_ipId].contains(_tag); - } /// @notice returns true if the ipId is tagged with any tag (meaning at least one dispute went through) /// @param _ipId The ipId function isIpTagged(address _ipId) external view returns (bool) { - return _taggedIpIds[_ipId].length() > 0; - } - - /// @notice returns the tags for a given ipId (note: this method could be expensive, use in frontends only) - /// @param _ipId The ipId - function ipTags(address _ipId) external view returns (bytes32[] memory) { - return _taggedIpIds[_ipId].values(); - } - - /// @notice returns the total tags for a given ipId - /// @param _ipId The ipId - function totalTagsForIp(address _ipId) external view returns (uint256) { - return _taggedIpIds[_ipId].length(); - } - - /// @notice returns the tag at a given index for a given ipId. No guarantees on ordering - /// @param _ipId The ipId - function tagForIpAt(address _ipId, uint256 _index) external view returns (bytes32) { - return _taggedIpIds[_ipId].at(_index); + return successfulDisputesPerIp[_ipId] > 0; } /// @notice Gets the protocol-wide module identifier for this module diff --git a/test/foundry/mocks/module/MockDisputeModule.sol b/test/foundry/mocks/module/MockDisputeModule.sol index 32b586791..3bb5499c7 100644 --- a/test/foundry/mocks/module/MockDisputeModule.sol +++ b/test/foundry/mocks/module/MockDisputeModule.sol @@ -123,24 +123,8 @@ contract MockDisputeModule is BaseModule, IDisputeModule { // These methods are not really used in the mock. They are just here to satisfy the interface. - function isIpTaggedWith(address, bytes32) external pure returns (bool) { - return false; - } - function isIpTagged(address) external pure returns (bool) { return false; } - function ipTags(address) external pure returns (bytes32[] memory) { - bytes32[] memory tags; - return tags; - } - - function totalTagsForIp(address) external pure returns (uint256) { - return 0; - } - - function tagForIpAt(address, uint256) external pure returns (bytes32) { - return bytes32(0); - } } diff --git a/test/foundry/modules/dispute/DisputeModule.t.sol b/test/foundry/modules/dispute/DisputeModule.t.sol index a5ce9e9d0..f3ed5b92a 100644 --- a/test/foundry/modules/dispute/DisputeModule.t.sol +++ b/test/foundry/modules/dispute/DisputeModule.t.sol @@ -391,13 +391,7 @@ contract DisputeModuleTest is BaseTest { assertEq(arbitrationPolicySPUSDCBalanceBefore - arbitrationPolicySPUSDCBalanceAfter, ARBITRATION_PRICE); assertEq(currentTagBefore, bytes32("IN_DISPUTE")); assertEq(currentTagAfter, bytes32("PLAGIARISM")); - assertTrue(disputeModule.isIpTaggedWith(ipAddr, bytes32("PLAGIARISM"))); assertTrue(disputeModule.isIpTagged(ipAddr)); - bytes32[] memory ipTags = new bytes32[](1); - ipTags[0] = bytes32("PLAGIARISM"); - assertEq(keccak256(abi.encode(disputeModule.ipTags(ipAddr))), keccak256(abi.encode(ipTags))); - assertEq(disputeModule.totalTagsForIp(ipAddr), 1); - assertEq(disputeModule.tagForIpAt(ipAddr, 0), bytes32("PLAGIARISM")); } function test_DisputeModule_PolicySP_setDisputeJudgement_False() public { @@ -426,11 +420,7 @@ contract DisputeModuleTest is BaseTest { assertEq(arbitrationPolicySPUSDCBalanceBefore - arbitrationPolicySPUSDCBalanceAfter, 0); assertEq(currentTagBefore, bytes32("IN_DISPUTE")); assertEq(currentTagAfter, bytes32(0)); - assertFalse(disputeModule.isIpTaggedWith(ipAddr, bytes32("PLAGIARISM"))); assertFalse(disputeModule.isIpTagged(ipAddr)); - bytes32[] memory ipTags = new bytes32[](0); - assertEq(keccak256(abi.encode(disputeModule.ipTags(ipAddr))), keccak256(abi.encode(ipTags))); - assertEq(disputeModule.totalTagsForIp(ipAddr), 0); } function test_DisputeModule_PolicySP_cancelDispute_revert_NotDisputeInitiator() public { @@ -469,11 +459,7 @@ contract DisputeModuleTest is BaseTest { assertEq(currentTagBeforeCancel, bytes32("IN_DISPUTE")); assertEq(currentTagAfterCancel, bytes32(0)); - assertFalse(disputeModule.isIpTaggedWith(ipAddr, bytes32("PLAGIARISM"))); assertFalse(disputeModule.isIpTagged(ipAddr)); - bytes32[] memory ipTags = new bytes32[](0); - assertEq(keccak256(abi.encode(disputeModule.ipTags(ipAddr))), keccak256(abi.encode(ipTags))); - assertEq(disputeModule.totalTagsForIp(ipAddr), 0); } function test_DisputeModule_resolveDispute_revert_NotDisputeInitiator() public { @@ -518,11 +504,7 @@ contract DisputeModuleTest is BaseTest { assertEq(currentTagBeforeResolve, bytes32("PLAGIARISM")); assertEq(currentTagAfterResolve, bytes32(0)); - assertFalse(disputeModule.isIpTaggedWith(ipAddr, bytes32("PLAGIARISM"))); assertFalse(disputeModule.isIpTagged(ipAddr)); - bytes32[] memory ipTags = new bytes32[](0); - assertEq(keccak256(abi.encode(disputeModule.ipTags(ipAddr))), keccak256(abi.encode(ipTags))); - assertEq(disputeModule.totalTagsForIp(ipAddr), 0); } function test_DisputeModule_name() public {