Skip to content
This repository has been archived by the owner on Apr 30, 2024. It is now read-only.

Commit

Permalink
feat: integration test fix, remove local vars, add reverts on verific…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
jdubpark committed Jan 26, 2024
1 parent a1810be commit 8def6d8
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 74 deletions.
91 changes: 56 additions & 35 deletions contracts/registries/LicenseRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { ILicenseRegistry } from "contracts/interfaces/registries/ILicenseRegist
import { Errors } from "contracts/lib/Errors.sol";
import { Licensing } from "contracts/lib/Licensing.sol";


// TODO: consider disabling operators/approvals on creation
contract LicenseRegistry is ERC1155, ILicenseRegistry {
using EnumerableSet for EnumerableSet.UintSet;
Expand Down Expand Up @@ -45,7 +44,7 @@ contract LicenseRegistry is ERC1155, ILicenseRegistry {
/// @dev ipId => policyId => PolicySetup
mapping(address => mapping(uint256 => PolicySetup)) private _policySetups;
mapping(address => EnumerableSet.UintSet) private _policiesPerIpId;

mapping(address => EnumerableSet.AddressSet) private _ipIdParents;

mapping(bytes32 => uint256) private _hashedLicenses;
Expand Down Expand Up @@ -93,19 +92,21 @@ contract LicenseRegistry is ERC1155, ILicenseRegistry {
}
params[paramName] = Licensing.Parameter({ verifier: verifier, defaultValue: fwCreation.defaultValues[i] });
}

emit LicenseFrameworkCreated(msg.sender, _totalFrameworks, fwCreation);
return _totalFrameworks;
}


/// Gets total frameworks supported by LicenseRegistry
function totalFrameworks() external view returns (uint256) {
return _totalFrameworks;
}

/// Returns framework for id. Reverts if not found
function frameworkParam(uint256 frameworkId, string calldata name) public view returns (Licensing.Parameter memory) {
function frameworkParam(
uint256 frameworkId,
string calldata name
) public view returns (Licensing.Parameter memory) {
Licensing.Framework storage fw = _framework(frameworkId);
return fw.parameters[ShortString.unwrap(name.toShortString())];
}
Expand Down Expand Up @@ -306,29 +307,31 @@ contract LicenseRegistry is ERC1155, ILicenseRegistry {
Licensing.Framework storage fw = _framework(pol.frameworkId);
uint256 policyParamsLength = pol.paramNames.length;
bool setByLinking = _policySetups[licensorIp][policyId].setByLinking;
bool verificationOk = true;
for (uint256 i = 0; i < policyParamsLength; i++) {
Licensing.Parameter memory param = fw.parameters[pol.paramNames[i]];

if (ERC165Checker.supportsInterface(address(param.verifier), type(IMintParamVerifier).interfaceId)) {
bytes memory data = pol.paramValues[i].length == 0 ? param.defaultValue : pol.paramValues[i];
verificationOk = IMintParamVerifier(address(param.verifier)).verifyMint(
bool verificationOk = IMintParamVerifier(address(param.verifier)).verifyMint(
msg.sender,
policyId,
setByLinking,
licensorIp,
receiver,
data
pol.paramValues[i].length == 0 ? param.defaultValue : pol.paramValues[i]
);

if (!verificationOk) {
revert Errors.LicenseRegistry__ParamVerifierFailed(
uint8(Licensing.ParamVerifierType.Mint),
address(param.verifier)
);
}
}
}

Licensing.License memory licenseData = Licensing.License({
policyId: policyId,
licensorIpId: licensorIp
});
(uint256 lId, bool isNew) = _addIdOrGetExisting(abi.encode(licenseData), _hashedLicenses, _totalLicenses);
licenseId = lId;

Licensing.License memory licenseData = Licensing.License({ policyId: policyId, licensorIpId: licensorIp });
bool isNew;
(licenseId, isNew) = _addIdOrGetExisting(abi.encode(licenseData), _hashedLicenses, _totalLicenses);
if (isNew) {
_totalLicenses = licenseId;
_licenses[licenseId] = licenseData;
Expand Down Expand Up @@ -376,23 +379,29 @@ contract LicenseRegistry is ERC1155, ILicenseRegistry {
// Verify linking params
Licensing.Policy memory pol = policy(licenseData.policyId);
Licensing.Framework storage fw = _framework(pol.frameworkId);
uint256 policyParamsLength = pol.paramNames.length;
bool verificationOk = true;
for (uint256 i = 0; i < policyParamsLength; i++) {

for (uint256 i = 0; i < pol.paramNames.length; i++) {
Licensing.Parameter memory param = fw.parameters[pol.paramNames[i]];

if (ERC165Checker.supportsInterface(address(param.verifier), type(ILinkParamVerifier).interfaceId)) {
bytes memory data = pol.paramValues[i].length == 0 ? param.defaultValue : pol.paramValues[i];
verificationOk = ILinkParamVerifier(address(param.verifier)).verifyLink(
bool verificationOk = ILinkParamVerifier(address(param.verifier)).verifyLink(
licenseId,
msg.sender,
childIpId,
parentIpId,
data
);

if (!verificationOk) {
revert Errors.LicenseRegistry__ParamVerifierFailed(
uint8(uint8(Licensing.ParamVerifierType.LinkParent)),
address(param.verifier)
);
}
}
}

// Add policy to kid
_addPolictyIdToIp(childIpId, licenseData.policyId, true);
// Set parent
Expand Down Expand Up @@ -424,36 +433,48 @@ contract LicenseRegistry is ERC1155, ILicenseRegistry {
return _licenses[licenseId].licensorIpId;
}

function _update(address from, address to, uint256[] memory ids, uint256[] memory values) virtual override internal {
function _update(
address from,
address to,
uint256[] memory licenseIds,
uint256[] memory values
) internal virtual override {
// We are interested in transfers, minting and burning are checked in mintLicense and linkIpToParent respectively.
if (from != address(0) && to != address(0)) {
uint256 length = ids.length;
for (uint256 i = 0; i < length; i++) {
for (uint256 i = 0; i < licenseIds.length; i++) {
// Verify transfer params
uint256 licenseId = ids[i];
Licensing.Policy memory pol = policy(_licenses[licenseId].policyId);
Licensing.Policy memory pol = policy(_licenses[licenseIds[i]].policyId);
Licensing.Framework storage fw = _framework(pol.frameworkId);
uint256 policyParamsLength = pol.paramNames.length;
bool verificationOk = true;
for (uint256 j = 0; j < policyParamsLength; j++) {
Licensing.Parameter memory param = fw.parameters[pol.paramNames[j]];
bytes memory paramValue = pol.paramValues[j];
if (ERC165Checker.supportsInterface(address(param.verifier), type(ITransferParamVerifier).interfaceId)) {
bytes memory data = paramValue.length == 0 ? param.defaultValue : paramValue;
verificationOk = ITransferParamVerifier(address(param.verifier)).verifyTransfer(
licenseId,
if (
ERC165Checker.supportsInterface(
address(param.verifier),
type(ITransferParamVerifier).interfaceId
)
) {
bool verificationOk = ITransferParamVerifier(address(param.verifier)).verifyTransfer(
licenseIds[i],
from,
to,
values[i],
data
paramValue.length == 0 ? param.defaultValue : paramValue
);

if (!verificationOk) {
revert Errors.LicenseRegistry__ParamVerifierFailed(
uint8(Licensing.ParamVerifierType.Transfer),
address(param.verifier)
);
}
}
}
}
}
}
super._update(from, to, ids, values);
super._update(from, to, licenseIds, values);
}


// TODO: tokenUri from parameters, from a metadata resolver contract
}
37 changes: 18 additions & 19 deletions test/foundry/integration/Integration.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,15 @@ contract IntegrationTest is Test {
defaultValues: byteValueTrue,
licenseUrl: "https://very-nice-verifier-license.com"
});

fwAllTrue.parameters[0] = byteValueTrue;
fwAllTrue.parameters[0] = mockLicenseVerifier;

Licensing.FrameworkCreationParams memory fwMintPayment = Licensing.FrameworkCreationParams({
parameters: new IParamVerifier[](1),
defaultValues: byteValueTrue,
licenseUrl: "https://expensive-minting-license.com"
});

fwMintPayment.mintingVerifiers[0] = mintPaymentVerifier;
fwMintPayment.parameters[0] = mintPaymentVerifier;

addLicenseFramework("all_true", fwAllTrue);
addLicenseFramework("mint_payment", fwMintPayment);
Expand All @@ -292,23 +291,27 @@ contract IntegrationTest is Test {

policy["test_true"] = Licensing.Policy({
frameworkId: licenseFwIds["all_true"],
mintingParamValues: new bytes[](1),
linkParentParamValues: new bytes[](1),
transferParamValues: new bytes[](1)
commercialUse: true,
derivatives: true,
paramNames: new bytes32[](1),
paramValues: new bytes[](1)
});

// TODO: test failure (verifier condition check fails) by setting to false
policy["test_true"].mintingParamValues[0] = abi.encode(true);
policy["test_true"].linkParentParamValues[0] = abi.encode(true);
policy["test_true"].transferParamValues[0] = abi.encode(true);
policy["test_true"].paramNames[0] = mockLicenseVerifier.name();
policy["test_true"].paramValues[0] = abi.encode(true);

policy["expensive_mint"] = Licensing.Policy({
frameworkId: licenseFwIds["mint_payment"],
mintingParamValues: new bytes[](1), // empty value to use default value, which doesn't matter
linkParentParamValues: new bytes[](0),
transferParamValues: new bytes[](0)
commercialUse: true,
derivatives: true,
paramNames: new bytes32[](1),
paramValues: new bytes[](1)
});

policy["expensive_mint"].paramNames[0] = mintPaymentVerifier.name();
// value doesn't matter bc mintPaymentVerifier ignores data (just requires payment)
policy["expensive_mint"].paramValues[0] = abi.encode(true);

licenseRegistry.addPolicy(policy["test_true"]);
licenseRegistry.addPolicy(policy["expensive_mint"]);

Expand All @@ -324,13 +327,11 @@ contract IntegrationTest is Test {
////////////////////////////////////////////////////////////////*/

uint256 policyId = policyIds["test_true"][getIpId(u.alice, nft.a, 1)];
address[] memory licensorIpIds = new address[](1);
licensorIpIds[0] = getIpId(u.alice, nft.a, 1);

// Carl mints 1 license for policy "test_true" on alice's NFT A IPAccount
licenseIds[u.carl][policyIds["test_true"][getIpId(u.alice, nft.a, 1)]] = licenseRegistry.mintLicense(
policyId,
licensorIpIds,
getIpId(u.alice, nft.a, 1),
1,
u.carl
);
Expand Down Expand Up @@ -373,8 +374,6 @@ contract IntegrationTest is Test {
vm.stopPrank();

policyId = policyIds["expensive_mint"][getIpId(u.carl, nft.c, 1)];
licensorIpIds = new address[](1);
licensorIpIds[0] = getIpId(u.carl, nft.c, 1);

// Bob mints 2 license for policy "expensive_mint" on carl's NFT C IPAccount

Expand All @@ -383,7 +382,7 @@ contract IntegrationTest is Test {

licenseIds[u.bob][policyIds["expensive_mint"][getIpId(u.carl, nft.c, 1)]] = licenseRegistry.mintLicense(
policyId,
licensorIpIds,
getIpId(u.carl, nft.c, 1),
2,
u.bob
);
Expand Down
2 changes: 1 addition & 1 deletion test/foundry/mocks/licensing/MintPaymentVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ contract MintPaymentVerifier is IParamVerifier, IMintParamVerifier, ERC165 {
address licensors,
address receiver,
bytes memory data
) external view returns (bool) {
) external returns (bool) {
// TODO: return false on approval or transfer failure
require(token.allowance(caller, address(this)) >= payment, "MintPaymentVerifier: Approval");
require(token.transferFrom(caller, address(this), payment), "MintPaymentVerifier: Transfer");
Expand Down
32 changes: 13 additions & 19 deletions test/foundry/modules/RegistrationModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,8 @@ contract RegistrationModuleTest is ModuleBaseTest {
);

// Mint license
address[] memory licensorIpIds = new address[](1);
licensorIpIds[0] = ipId;
uint256 licenseId = licenseRegistry.mintLicense(policyId, licensorIpIds, 1, bob);
address licensorIpId = ipId;
uint256 licenseId = licenseRegistry.mintLicense(policyId, licensorIpId, 1, bob);
uint256 totalSupply = ipRecordRegistry.totalSupply();


Expand Down Expand Up @@ -216,30 +215,25 @@ contract RegistrationModuleTest is ModuleBaseTest {
mintingVerifiers[0] = verifier;
bytes[] memory mintingDefaultValues = new bytes[](1);
mintingDefaultValues[0] = abi.encode(true);
IParamVerifier[] memory linkParentVerifiers = new IParamVerifier[](1);
linkParentVerifiers[0] = verifier;
bytes[] memory linkParentDefaultValues = new bytes[](1);
linkParentDefaultValues[0] = abi.encode(true);

IParamVerifier[] memory parameters;
bytes[] memory defaultValues;

Licensing.FrameworkCreationParams memory fwParams = Licensing.FrameworkCreationParams({
mintingVerifiers: mintingVerifiers,
mintingDefaultValues: mintingDefaultValues,
linkParentVerifiers: linkParentVerifiers,
linkParentDefaultValues: linkParentDefaultValues,
transferVerifiers: new IParamVerifier[](0),
transferDefaultValues: new bytes[](0),
parameters: mintingVerifiers,
defaultValues: mintingDefaultValues,
licenseUrl: "https://example.com"
});
licenseRegistry.addLicenseFramework(fwParams);
Licensing.Policy memory policy = Licensing.Policy({
frameworkId: 1,
mintingParamValues: new bytes[](1),
linkParentParamValues: new bytes[](1),
transferParamValues: new bytes[](1)
commercialUse: true,
derivatives: true,
paramNames: new bytes32[](1),
paramValues: new bytes[](1)
});
policy.mintingParamValues[0] = abi.encode(true);
policy.linkParentParamValues[0] = abi.encode(true);
policy.transferParamValues[0] = abi.encode(true);
policy.paramNames[0] = verifier.name();
policy.paramValues[0] = abi.encode(true);
(uint256 polId) = licenseRegistry.addPolicy(policy);

policyId = polId;
Expand Down

0 comments on commit 8def6d8

Please sign in to comment.