Skip to content

Commit

Permalink
Add dispute propagation restriction (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
Spablob authored and kingster-will committed Jan 31, 2025
1 parent 13dd254 commit 212f610
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
3 changes: 3 additions & 0 deletions contracts/lib/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,9 @@ library Errors {
/// @notice Provided parent dispute's target IP is not the derivative IP's parent.
error DisputeModule__NotDerivative();

/// @notice Provided parent dispute has already been propagated to the derivative IP.
error DisputeModule__DisputeAlreadyPropagated();

/// @notice Provided parent dispute has not been resolved.
error DisputeModule__ParentDisputeNotResolved();

Expand Down
5 changes: 5 additions & 0 deletions contracts/modules/dispute/DisputeModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ contract DisputeModule is
/// @param nextArbitrationPolicies Next arbitration policy for a given ipId
/// @param arbitrationUpdateTimestamps Timestamp of when the arbitration policy will be updated for a given ipId
/// @param successfulDisputesPerIp Counter of successful disputes per ipId
/// @param isDisputePropagated Indicates if a dispute has been propagated from a parent ipId to a derivative ipId
/// @custom:storage-location erc7201:story-protocol.DisputeModule
struct DisputeModuleStorage {
uint256 disputeCounter;
Expand All @@ -54,6 +55,7 @@ contract DisputeModule is
mapping(address ipId => address) nextArbitrationPolicies;
mapping(address ipId => uint256) nextArbitrationUpdateTimestamps;
mapping(address ipId => uint256) successfulDisputesPerIp;
mapping(address ipId => mapping(address parentIpId => mapping(uint256 disputeId => bool))) isDisputePropagated;
}

// keccak256(abi.encode(uint256(keccak256("story-protocol.DisputeModule")) - 1)) & ~bytes32(uint256(0xff));
Expand Down Expand Up @@ -296,6 +298,8 @@ contract DisputeModule is
revert Errors.DisputeModule__ParentNotTagged();

if (!LICENSE_REGISTRY.isParentIp(parentIpId, derivativeIpId)) revert Errors.DisputeModule__NotDerivative();
if ($.isDisputePropagated[derivativeIpId][parentIpId][parentDisputeId])
revert Errors.DisputeModule__DisputeAlreadyPropagated();

uint256 disputeId = ++$.disputeCounter;
uint256 disputeTimestamp = block.timestamp;
Expand All @@ -311,6 +315,7 @@ contract DisputeModule is
parentDisputeId: parentDisputeId
});

$.isDisputePropagated[derivativeIpId][parentIpId][parentDisputeId] = true;
$.successfulDisputesPerIp[derivativeIpId]++;

emit DerivativeTaggedOnParentInfringement(
Expand Down
19 changes: 19 additions & 0 deletions test/foundry/modules/dispute/DisputeModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,25 @@ contract DisputeModuleTest is BaseTest {
disputeModule.tagDerivativeIfParentInfringed(ipAddr, ipAddr2, 1);
}

function test_DisputeModule_tagDerivativeIfParentInfringed_revert_DisputeAlreadyPropagated() public {
// raise dispute
vm.startPrank(ipAccount1);
IERC20(USDC).approve(address(mockArbitrationPolicy), ARBITRATION_PRICE);
disputeModule.raiseDispute(ipAddr, disputeEvidenceHashExample, "IMPROPER_REGISTRATION", "");
vm.stopPrank();

// set dispute judgement
vm.startPrank(arbitrationRelayer);
disputeModule.setDisputeJudgement(1, true, "");
vm.stopPrank();

assertEq(licenseRegistry.isParentIp(ipAddr, ipAddr2), true);

disputeModule.tagDerivativeIfParentInfringed(ipAddr, ipAddr2, 1);
vm.expectRevert(Errors.DisputeModule__DisputeAlreadyPropagated.selector);
disputeModule.tagDerivativeIfParentInfringed(ipAddr, ipAddr2, 1);
}

function test_DisputeModule_tagDerivativeIfParentInfringed_revert_NotDerivative() public {
// raise dispute
vm.startPrank(ipAccount1);
Expand Down

0 comments on commit 212f610

Please sign in to comment.