Skip to content

Commit

Permalink
opt(licensing): rm hasIpAttachedLicenseTerms check (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebsadface authored Sep 30, 2024
1 parent d7a4f19 commit 53b1e87
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 5 deletions.
16 changes: 11 additions & 5 deletions contracts/lib/LicensingHelper.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import { ILicenseRegistry } from "@storyprotocol/core/interfaces/registries/ILicenseRegistry.sol";
import { Errors as CoreErrors } from "@storyprotocol/core/lib/Errors.sol";
import { ILicensingModule } from "@storyprotocol/core/interfaces/modules/licensing/ILicensingModule.sol";
import { IPILicenseTemplate, PILTerms } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";

Expand Down Expand Up @@ -40,9 +40,15 @@ library LicensingHelper {
address licenseTemplate,
uint256 licenseTermsId
) internal {
// Returns if license terms are already attached.
if (ILicenseRegistry(licenseRegistry).hasIpAttachedLicenseTerms(ipId, licenseTemplate, licenseTermsId)) return;

ILicensingModule(licensingModule).attachLicenseTerms(ipId, licenseTemplate, licenseTermsId);
try ILicensingModule(licensingModule).attachLicenseTerms(ipId, licenseTemplate, licenseTermsId) {
return; // license terms are attached successfully
} catch (bytes memory reason) {
// if the error is not that the license terms are already attached, revert with the original error
if (CoreErrors.LicenseRegistry__LicenseTermsAlreadyAttached.selector != bytes4(reason)) {
assembly {
revert(add(reason, 32), mload(reason))
}
}
}
}
}
115 changes: 115 additions & 0 deletions test/workflows/LicenseAttachmentWorkflows.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity 0.8.26;

// external
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { Errors as CoreErrors } from "@storyprotocol/core/lib/Errors.sol";
import { ICoreMetadataModule } from "@storyprotocol/core/interfaces/modules/metadata/ICoreMetadataModule.sol";
import { IIPAccount } from "@storyprotocol/core/interfaces/IIPAccount.sol";
import { ILicensingModule } from "@storyprotocol/core/interfaces/modules/licensing/ILicensingModule.sol";
Expand Down Expand Up @@ -158,4 +159,118 @@ contract LicenseAttachmentWorkflowsTest is BaseTest {
sigAttach: WorkflowStructs.SignatureData({ signer: u.alice, deadline: deadline, signature: sigAttach })
});
}

function test_LicenseAttachmentWorkflows_registerPILTermsAndAttach_idempotency()
public
withCollection
withIp(u.alice)
{
address payable ipId = ipAsset[1].ipId;
uint256 deadline = block.timestamp + 1000;

(bytes memory signature, , bytes memory data) = _getSetPermissionSigForPeriphery({
ipId: ipId,
to: address(licenseAttachmentWorkflows),
module: address(licensingModule),
selector: ILicensingModule.attachLicenseTerms.selector,
deadline: deadline,
state: IIPAccount(ipId).state(),
signerSk: sk.alice
});

IIPAccount(ipId).executeWithSig({
to: address(accessController),
value: 0,
data: data,
signer: u.alice,
deadline: deadline,
signature: signature
});

uint256 licenseTermsId1 = licenseAttachmentWorkflows.registerPILTermsAndAttach({
ipId: ipId,
terms: PILFlavors.commercialUse({
mintingFee: 100,
currencyToken: address(mockToken),
royaltyPolicy: address(royaltyPolicyLAP)
})
});

// attach the same license terms to the IP again, but it shouldn't revert
uint256 licenseTermsId2 = licenseAttachmentWorkflows.registerPILTermsAndAttach({
ipId: ipId,
terms: PILFlavors.commercialUse({
mintingFee: 100,
currencyToken: address(mockToken),
royaltyPolicy: address(royaltyPolicyLAP)
})
});

assertEq(licenseTermsId1, licenseTermsId2);
}

function test_revert_registerPILTermsAndAttach_DerivativesCannotAddLicenseTerms()
public
withCollection
whenCallerHasMinterRole
withEnoughTokens(address(licenseAttachmentWorkflows))
{
(address ipIdParent, , uint256 licenseTermsIdParent) = licenseAttachmentWorkflows
.mintAndRegisterIpAndAttachPILTerms({
spgNftContract: address(nftContract),
recipient: caller,
ipMetadata: ipMetadataDefault,
terms: PILFlavors.nonCommercialSocialRemixing()
});

address[] memory parentIpIds = new address[](1);
parentIpIds[0] = ipIdParent;

uint256[] memory licenseTermsIds = new uint256[](1);
licenseTermsIds[0] = licenseTermsIdParent;

(address ipIdChild, uint256 tokenIdChild) = derivativeWorkflows.mintAndRegisterIpAndMakeDerivative({
spgNftContract: address(nftContract),
derivData: WorkflowStructs.MakeDerivative({
parentIpIds: parentIpIds,
licenseTemplate: address(pilTemplate),
licenseTermsIds: licenseTermsIds,
royaltyContext: ""
}),
ipMetadata: ipMetadataDefault,
recipient: caller
});

uint256 deadline = block.timestamp + 1000;

(bytes memory signature, , bytes memory data) = _getSetPermissionSigForPeriphery({
ipId: ipIdChild,
to: address(licenseAttachmentWorkflows),
module: address(licensingModule),
selector: ILicensingModule.attachLicenseTerms.selector,
deadline: deadline,
state: IIPAccount(payable(ipIdChild)).state(),
signerSk: sk.alice
});

IIPAccount(payable(ipIdChild)).executeWithSig({
to: address(accessController),
value: 0,
data: data,
signer: u.alice,
deadline: deadline,
signature: signature
});

// attach a different license terms to the child ip, should revert with the correct error
vm.expectRevert(CoreErrors.LicensingModule__DerivativesCannotAddLicenseTerms.selector);
licenseAttachmentWorkflows.registerPILTermsAndAttach({
ipId: ipIdChild,
terms: PILFlavors.commercialUse({
mintingFee: 100,
currencyToken: address(mockToken),
royaltyPolicy: address(royaltyPolicyLAP)
})
});
}
}

0 comments on commit 53b1e87

Please sign in to comment.