Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions contracts/src/registry/PermissionedRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {IPermissionedRegistry} from "./interfaces/IPermissionedRegistry.sol";
import {IRegistry} from "./interfaces/IRegistry.sol";
import {IRegistryMetadata} from "./interfaces/IRegistryMetadata.sol";
import {IStandardRegistry} from "./interfaces/IStandardRegistry.sol";
import {ITemporalRegistry} from "./interfaces/ITemporalRegistry.sol";
import {ITokenizedRegistry} from "./interfaces/ITokenizedRegistry.sol";
import {RegistryRolesLib} from "./libraries/RegistryRolesLib.sol";
import {MetadataMixin} from "./MetadataMixin.sol";

Expand Down Expand Up @@ -119,6 +121,8 @@ contract PermissionedRegistry is
{
return
interfaceId == type(IPermissionedRegistry).interfaceId ||
interfaceId == type(ITokenizedRegistry).interfaceId ||
interfaceId == type(ITemporalRegistry).interfaceId ||
interfaceId == type(IStandardRegistry).interfaceId ||
interfaceId == type(IRegistry).interfaceId ||
super.supportsInterface(interfaceId);
Expand All @@ -128,6 +132,17 @@ contract PermissionedRegistry is
// Implementation
////////////////////////////////////////////////////////////////////////

/// @inheritdoc ITemporalRegistry
function findExpiry(string calldata label) external view returns (uint64) {
return getExpiry(LibLabel.id(label));
}

/// @inheritdoc ITokenizedRegistry
function findTokenId(string calldata label) external view returns (uint256 tokenId) {
tokenId = LibLabel.id(label);
tokenId = _constructTokenId(tokenId, _entry(tokenId));
}

/// @inheritdoc IStandardRegistry
function setSubregistry(uint256 anyId, IRegistry registry) public virtual {
(uint256 tokenId, Entry storage entry) = _checkExpiryAndTokenRoles(
Expand Down
8 changes: 4 additions & 4 deletions contracts/src/registry/interfaces/IStandardRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;

import {IERC1155Singleton} from "../../erc1155/interfaces/IERC1155Singleton.sol";

import {IRegistry} from "./IRegistry.sol";
import {ITemporalRegistry} from "./ITemporalRegistry.sol";
import {ITokenizedRegistry} from "./ITokenizedRegistry.sol";

/// @title IStandardRegistry
/// @notice A tokenized registry.
/// @notice A tokenized registry with registrations that expire.
/// @dev Interface selector: `0xb844ab6c`
interface IStandardRegistry is IRegistry, IERC1155Singleton {
interface IStandardRegistry is ITemporalRegistry, ITokenizedRegistry {
////////////////////////////////////////////////////////////////////////
// Errors
////////////////////////////////////////////////////////////////////////
Expand Down
13 changes: 13 additions & 0 deletions contracts/src/registry/interfaces/ITemporalRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;

import {IRegistry} from "./IRegistry.sol";

/// @notice A registry with expirations.
/// @dev Interface selector: `0x6f537c72`
interface ITemporalRegistry is IRegistry {
/// @notice Fetches the label expiry.
/// @param label The label to query.
/// @return The expiry of the label.
function findExpiry(string calldata label) external view returns (uint64);
}
15 changes: 15 additions & 0 deletions contracts/src/registry/interfaces/ITokenizedRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;

import {IERC1155Singleton} from "../../erc1155/interfaces/IERC1155Singleton.sol";

import {IRegistry} from "./IRegistry.sol";

/// @notice A tokenized registry.
/// @dev Interface selector: `0x91b3c037`
interface ITokenizedRegistry is IRegistry, IERC1155Singleton {
/// @notice Fetches the token ID for a label.
/// @param label The label to query.
/// @return The token ID of the label.
function findTokenId(string calldata label) external view returns (uint256);
}
34 changes: 34 additions & 0 deletions contracts/test/unit/registry/PermissionedRegistry.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
IPermissionedRegistry,
IEnhancedAccessControl,
IRegistry,
ITokenizedRegistry,
ITemporalRegistry,
IStandardRegistry,
IRegistryMetadata,
IHCAFactoryBasic,
Expand Down Expand Up @@ -60,6 +62,14 @@ contract PermissionedRegistryTest is Test, ERC1155Holder {
registry.supportsInterface(type(IStandardRegistry).interfaceId),
"IStandardRegistry"
);
assertTrue(
registry.supportsInterface(type(ITokenizedRegistry).interfaceId),
"ITokenizedRegistry"
);
assertTrue(
registry.supportsInterface(type(ITemporalRegistry).interfaceId),
"ITemporalRegistry"
);
assertTrue(
registry.supportsInterface(type(IPermissionedRegistry).interfaceId),
"IPermissionedRegistry"
Expand Down Expand Up @@ -885,6 +895,30 @@ contract PermissionedRegistryTest is Test, ERC1155Holder {
assertEq(counts, testRoles);
}

////////////////////////////////////////////////////////////////////////
// Low-level Interfaces
////////////////////////////////////////////////////////////////////////

function test_findExpiry() external {
assertEq(registry.findExpiry(testLabel), 0);
uint256 tokenId = this._register();
assertEq(registry.findExpiry(testLabel), testExpiry);
registry.unregister(tokenId);
assertEq(registry.findExpiry(testLabel), block.timestamp, "burn");
this._register();
assertEq(registry.findExpiry(testLabel), testExpiry, "again");
}

function test_findTokenId() external {
assertEq(registry.findTokenId(testLabel), LibLabel.withVersion(LibLabel.id(testLabel), 0));
uint256 tokenId = this._register();
assertEq(registry.findTokenId(testLabel), tokenId);
registry.unregister(tokenId);
assertEq(registry.findTokenId(testLabel), tokenId + 1, "burn");
tokenId = this._register();
assertEq(registry.findTokenId(testLabel), tokenId, "again");
}

////////////////////////////////////////////////////////////////////////
// Token Regeneration
////////////////////////////////////////////////////////////////////////
Expand Down
Loading