// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.26;
import { Test } from "forge-std/Test.sol";
// for testing purposes only
import { MockIPGraph } from "@storyprotocol/test/mocks/MockIPGraph.sol";
import { IIPAssetRegistry } from "@storyprotocol/core/interfaces/registries/IIPAssetRegistry.sol";
import { ILicenseRegistry } from "@storyprotocol/core/interfaces/registries/ILicenseRegistry.sol";
import { IPILicenseTemplate } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";
import { ILicensingModule } from "@storyprotocol/core/interfaces/modules/licensing/ILicensingModule.sol";
import { PILFlavors } from "@storyprotocol/core/lib/PILFlavors.sol";
import { PILTerms } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";
import { SimpleNFT } from "../src/mocks/SimpleNFT.sol";
// Run this test:
// forge test --fork-url https://aeneid.storyrpc.io/ --match-path test/4_IPARemix.t.sol
contract IPARemixTest is Test {
address internal alice = address(0xa11ce);
address internal bob = address(0xb0b);
// For addresses, see https://docs.story.foundation/developers/deployed-smart-contracts
// Protocol Core - IPAssetRegistry
IIPAssetRegistry internal IP_ASSET_REGISTRY = IIPAssetRegistry(0x77319B4031e6eF1250907aa00018B8B1c67a244b);
// Protocol Core - LicenseRegistry
ILicenseRegistry internal LICENSE_REGISTRY = ILicenseRegistry(0x529a750E02d8E2f15649c13D69a465286a780e24);
// Protocol Core - LicensingModule
ILicensingModule internal LICENSING_MODULE = ILicensingModule(0x04fbd8a2e56dd85CFD5500A4A4DfA955B9f1dE6f);
// Protocol Core - PILicenseTemplate
IPILicenseTemplate internal PIL_TEMPLATE = IPILicenseTemplate(0x2E896b0b2Fdb7457499B56AAaA4AE55BCB4Cd316);
// Protocol Core - RoyaltyPolicyLAP
address internal ROYALTY_POLICY_LAP = 0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E;
// Revenue Token - MERC20
address internal MERC20 = 0xF2104833d386a2734a4eB3B8ad6FC6812F29E38E;
SimpleNFT public SIMPLE_NFT;
uint256 public tokenId;
address public ipId;
uint256 public licenseTermsId;
uint256 public startLicenseTokenId;
function setUp() public {
// this is only for testing purposes
// due to our IPGraph precompile not being
// deployed on the fork
vm.etch(address(0x0101), address(new MockIPGraph()).code);
SIMPLE_NFT = new SimpleNFT("Simple IP NFT", "SIM");
tokenId = SIMPLE_NFT.mint(alice);
ipId = IP_ASSET_REGISTRY.register(block.chainid, address(SIMPLE_NFT), tokenId);
licenseTermsId = PIL_TEMPLATE.registerLicenseTerms(
PILFlavors.commercialRemix({
mintingFee: 0,
commercialRevShare: 10 * 10 ** 6, // 10%
royaltyPolicy: ROYALTY_POLICY_LAP,
currencyToken: MERC20
})
);
vm.prank(alice);
LICENSING_MODULE.attachLicenseTerms(ipId, address(PIL_TEMPLATE), licenseTermsId);
startLicenseTokenId = LICENSING_MODULE.mintLicenseTokens({
licensorIpId: ipId,
licenseTemplate: address(PIL_TEMPLATE),
licenseTermsId: licenseTermsId,
amount: 2,
receiver: bob,
royaltyContext: "", // for PIL, royaltyContext is empty string
maxMintingFee: 0,
maxRevenueShare: 0
});
}
/// @notice Mints an NFT to be registered as IP, and then
/// linked as a derivative of alice's asset using the
/// minted license token.
function test_registerDerivativeWithLicenseTokens() public {
// First we mint an NFT and register it as an IP Asset,
// owned by Bob.
uint256 childTokenId = SIMPLE_NFT.mint(bob);
address childIpId = IP_ASSET_REGISTRY.register(block.chainid, address(SIMPLE_NFT), childTokenId);
uint256[] memory licenseTokenIds = new uint256[](1);
licenseTokenIds[0] = startLicenseTokenId;
// Bob uses the License Token he has from Alice's IP
// to register his IP as a derivative of Alice's IP.
vm.prank(bob);
LICENSING_MODULE.registerDerivativeWithLicenseTokens({
childIpId: childIpId,
licenseTokenIds: licenseTokenIds,
royaltyContext: "", // empty for PIL
maxRts: 0
});
assertTrue(LICENSE_REGISTRY.hasDerivativeIps(ipId));
assertTrue(LICENSE_REGISTRY.isParentIp(ipId, childIpId));
assertTrue(LICENSE_REGISTRY.isDerivativeIp(childIpId));
assertEq(LICENSE_REGISTRY.getParentIpCount(childIpId), 1);
assertEq(LICENSE_REGISTRY.getDerivativeIpCount(ipId), 1);
assertEq(LICENSE_REGISTRY.getParentIp({ childIpId: childIpId, index: 0 }), ipId);
assertEq(LICENSE_REGISTRY.getDerivativeIp({ parentIpId: ipId, index: 0 }), childIpId);
}
}