From dba4d74081a6cb05f21d0039e746c93336ef6fda Mon Sep 17 00:00:00 2001 From: Leeren Chang Date: Fri, 19 Jan 2024 22:32:50 -0800 Subject: [PATCH] Fixes PR reviews --- .../interfaces/erc6551/IERC6551Registry.sol | 34 ------ contracts/lib/IP.sol | 8 +- contracts/registries/IPRecordRegistry.sol | 2 + test/foundry/ModuleRegistry.t.sol | 4 +- test/foundry/mocks/MockERC6551Registry.sol | 107 ------------------ 5 files changed, 10 insertions(+), 145 deletions(-) delete mode 100644 contracts/interfaces/erc6551/IERC6551Registry.sol delete mode 100644 test/foundry/mocks/MockERC6551Registry.sol diff --git a/contracts/interfaces/erc6551/IERC6551Registry.sol b/contracts/interfaces/erc6551/IERC6551Registry.sol deleted file mode 100644 index 4ef04972..00000000 --- a/contracts/interfaces/erc6551/IERC6551Registry.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -interface IERC6551Registry { - - /// @notice Emits when a new ERC6551 account is created. - event AccountCreated( - address account, - address indexed implementation, - uint256 chainId, - address indexed tokenContract, - uint256 indexed tokenId, - uint256 salt - ); - - /// @notice Creates a new token-bound account for an NFT. - function createAccount( - address implementation, - uint256 chainId, - address tokenContract, - uint256 tokenId, - uint256 seed, - bytes calldata initData - ) external returns (address); - - /// @notice Retrieves the token-bound account address for an NFT. - function account( - address implementation, - uint256 chainId, - address tokenContract, - uint256 tokenId, - uint256 salt - ) external view returns (address); -} diff --git a/contracts/lib/IP.sol b/contracts/lib/IP.sol index 78cfc259..341ddef4 100644 --- a/contracts/lib/IP.sol +++ b/contracts/lib/IP.sol @@ -6,6 +6,9 @@ pragma solidity ^0.8.21; /// @notice Library for constants, structs, and helper functions used for IP. library IP { /// @notice Core metadata associated with an IP. + /// @dev This is what is fetched when `metadata()` is called from an IP + /// resolver, and includes aggregated attributes fetched from various + /// modules in addition to that which is stored on the resolver itself. struct Metadata { // The current owner of the IP. address owner; @@ -24,8 +27,9 @@ library IP { } /// @notice Core metadata exclusively saved by the IP resolver. - /// @dev Resolved attributes not referenced here are processed through - /// their corresponding data modules (e.g. licensing for license data). + /// @dev This only encompasses metadata which is stored on the IP metadata + /// resolver itself, and does not include those attributes which may + /// be fetched from different modules (e.g. the licensing modules). struct MetadataRecord { // The name associated with the IP. string name; diff --git a/contracts/registries/IPRecordRegistry.sol b/contracts/registries/IPRecordRegistry.sol index 2e8b5fc1..4ca03dda 100644 --- a/contracts/registries/IPRecordRegistry.sol +++ b/contracts/registries/IPRecordRegistry.sol @@ -130,6 +130,7 @@ contract IPRecordRegistry is IIPRecordRegistry { /// @param tokenId The token identifier of the NFT. function createIPAccount(uint256 chainId, address tokenContract, uint256 tokenId) external returns (address) { address account = IP_ACCOUNT_REGISTRY.ipAccount(chainId, tokenContract, tokenId); + // TODO: Finalize disambiguation between IP accounts and IP identifiers. if (account.code.length != 0) { revert Errors.IPRecordRegistry_IPAccountAlreadyCreated(); } @@ -158,6 +159,7 @@ contract IPRecordRegistry is IIPRecordRegistry { if (resolverAddr == address(0)) { revert Errors.IPRecordRegistry_ResolverInvalid(); } + // Resolvers may not be set unless the IP was registered into the protocol. if (_resolvers[id] == address(0)) { revert Errors.IPRecordRegistry_NotYetRegistered(); } diff --git a/test/foundry/ModuleRegistry.t.sol b/test/foundry/ModuleRegistry.t.sol index aa856ce9..13cd53a9 100644 --- a/test/foundry/ModuleRegistry.t.sol +++ b/test/foundry/ModuleRegistry.t.sol @@ -8,7 +8,7 @@ import "contracts/IPAccountImpl.sol"; import "contracts/interfaces/IIPAccount.sol"; import "lib/reference/src/interfaces/IERC6551Account.sol"; import "test/foundry/mocks/MockERC721.sol"; -import { MockERC6551Registry} from "test/foundry/mocks/MockERC6551Registry.sol"; +import { ERC6551Registry } from "lib/reference/src/ERC6551Registry.sol"; import "test/foundry/mocks/MockAccessController.sol"; import "test/foundry/mocks/MockModule.sol"; import "contracts/registries/ModuleRegistry.sol"; @@ -18,7 +18,7 @@ contract ModuleRegistryTest is Test { IPAccountRegistry public registry; IPAccountImpl public implementation; ModuleRegistry public moduleRegistry = new ModuleRegistry(); - MockERC6551Registry public erc6551Registry = new MockERC6551Registry(); + ERC6551Registry public erc6551Registry = new ERC6551Registry(); MockAccessController public accessController = new MockAccessController(); MockModule public module; diff --git a/test/foundry/mocks/MockERC6551Registry.sol b/test/foundry/mocks/MockERC6551Registry.sol deleted file mode 100644 index 857a7a89..00000000 --- a/test/foundry/mocks/MockERC6551Registry.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.23; - -import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; -import { IERC6551Registry } from 'contracts/interfaces/erc6551/IERC6551Registry.sol'; - -contract MockERC6551Registry is IERC6551Registry { - - /// @notice Creates a new token-bound account for an NFT. - function createAccount( - address implementation, - uint256 chainId, - address tokenContract, - uint256 tokenId, - uint256 salt, - bytes calldata initData - ) external returns (address) { - bytes memory code = _getCreationCode( - implementation, - chainId, - tokenContract, - tokenId, - salt - ); - - address _account = Create2.computeAddress(bytes32(salt), keccak256(code)); - - if (_account.code.length != 0) return _account; - - emit AccountCreated(_account, implementation, chainId, tokenContract, tokenId, salt); - - _account = Create2.deploy(0, bytes32(salt), code); - - if (initData.length != 0) { - (bool success, bytes memory result) = _account.call(initData); - if (!success) { - assembly { - revert(add(result, 32), mload(result)) - } - } - } - - return _account; - } - - /// @notice Retrieves the token-bound account address for an NFT. - function account( - address implementation, - uint256 chainId, - address tokenContract, - uint256 tokenId, - uint256 salt - ) external view returns (address) { - bytes32 bytecodeHash = keccak256( - _getCreationCode( - implementation, - chainId, - tokenContract, - tokenId, - salt - ) - ); - - return Create2.computeAddress(bytes32(salt), bytecodeHash); - } - - function _getCreationCode( - address implementation_, - uint256 chainId_, - address tokenContract_, - uint256 tokenId_, - uint256 salt_ - ) internal pure returns (bytes memory) { - return - // Proxy that delegate call to IPAccountProxy - // | 0x00000000 36 calldatasize cds - // | 0x00000001 3d returndatasize 0 cds - // | 0x00000002 3d returndatasize 0 0 cds - // | 0x00000003 37 calldatacopy - // | 0x00000004 3d returndatasize 0 - // | 0x00000005 3d returndatasize 0 0 - // | 0x00000006 3d returndatasize 0 0 0 - // | 0x00000007 36 calldatasize cds 0 0 0 - // | 0x00000008 3d returndatasize 0 cds 0 0 0 - // | 0x00000009 73bebebebebe. push20 0xbebebebe 0xbebe 0 cds 0 0 0 - // | 0x0000001e 5a gas gas 0xbebe 0 cds 0 0 0 - // | 0x0000001f f4 delegatecall suc 0 - // | 0x00000020 3d returndatasize rds suc 0 - // | 0x00000021 82 dup3 0 rds suc 0 - // | 0x00000022 80 dup1 0 0 rds suc 0 - // | 0x00000023 3e returndatacopy suc 0 - // | 0x00000024 90 swap1 0 suc - // | 0x00000025 3d returndatasize rds 0 suc - // | 0x00000026 91 swap2 suc 0 rds - // | 0x00000027 602b push1 0x2b 0x2b suc 0 rds - // | ,=< 0x00000029 57 jumpi 0 rds - // | | 0x0000002a fd revert - // | `-> 0x0000002b 5b jumpdest 0 rds - // \ 0x0000002c f3 return - abi.encodePacked( - hex"3d60ad80600a3d3981f3363d3d373d3d3d363d73", - implementation_, - hex"5af43d82803e903d91602b57fd5bf3", - abi.encode(salt_, chainId_, tokenContract_, tokenId_) - ); - } -}