Skip to content

Commit

Permalink
constructor up
Browse files Browse the repository at this point in the history
  • Loading branch information
mejango committed Aug 20, 2024
1 parent ff64a7f commit 2ca0059
Showing 1 changed file with 66 additions and 34 deletions.
100 changes: 66 additions & 34 deletions src/JBProjectHandles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {

/// @notice The ENS registry contract address.
/// @dev Same on Ethereum mainnet and most of its testnets.
ENS public constant override ENS_REGISTRY = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
ENS public constant override ENS_REGISTRY =
ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);

//*********************************************************************//
// --------------------- private stored properties ------------------- //
Expand All @@ -43,8 +44,15 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
/// @custom:param chainId The chain ID of the network the project is on.
/// @custom:param projectId The ID of the project to get the ENS parts of.
/// @custom:param setter The address that set the requested `ensParts`. This should be the project's current owner.
mapping(uint256 chainId => mapping(uint256 projectId => mapping(address setter => string[] ensParts))) private
_ensNamePartsOf;
mapping(uint256 chainId => mapping(uint256 projectId => mapping(address setter => string[] ensParts)))
private _ensNamePartsOf;

//*********************************************************************//
// ---------------------------- constructor -------------------------- //
//*********************************************************************//

/// @param trustedForwarder The trusted forwarder for the ERC2771Context.
constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {}

//*********************************************************************//
// ------------------------- external views -------------------------- //
Expand All @@ -59,12 +67,7 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
uint256 chainId,
uint256 projectId,
address setter
)
external
view
override
returns (string[] memory)
{
) external view override returns (string[] memory) {
return _ensNamePartsOf[chainId][projectId][setter];
}

Expand All @@ -78,14 +81,11 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
uint256 chainId,
uint256 projectId,
address setter
)
external
view
override
returns (string memory)
{
) external view override returns (string memory) {
// Get a reference to the project's ENS name parts.
string[] memory ensNameParts = _ensNamePartsOf[chainId][projectId][setter];
string[] memory ensNameParts = _ensNamePartsOf[chainId][projectId][
setter
];

// Return an empty string if not found.
if (ensNameParts.length == 0) return "";
Expand All @@ -100,12 +100,23 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
if (textResolver == address(0)) return "";

// Find the `projectId` that the text record of the ENS name is mapped to.
string memory textRecord = ITextResolver(textResolver).text(hashedName, TEXT_KEY);
string memory textRecord = ITextResolver(textResolver).text(
hashedName,
TEXT_KEY
);

// Return empty string if text record from ENS name doesn't match `projectId` and `chainId`.
if (
keccak256(bytes(textRecord))
!= keccak256(bytes(string.concat(Strings.toString(chainId), ":", Strings.toString(projectId))))
keccak256(bytes(textRecord)) !=
keccak256(
bytes(
string.concat(
Strings.toString(chainId),
":",
Strings.toString(projectId)
)
)
)
) return "";

// Format the handle from the name parts.
Expand All @@ -117,22 +128,32 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
//*********************************************************************//

/// @dev ERC-2771 specifies the context as being a single address (20 bytes).
function _contextSuffixLength() internal view virtual override returns (uint256) {
function _contextSuffixLength()
internal
view
virtual
override
returns (uint256)
{
return super._contextSuffixLength();
}

/// @notice Formats ENS name parts into a handle.
/// @param ensNameParts The ENS name parts to format into a handle.
/// @return handle The formatted ENS handle.
function _formatHandle(string[] memory ensNameParts) internal pure returns (string memory handle) {
function _formatHandle(
string[] memory ensNameParts
) internal pure returns (string memory handle) {
// Get a reference to the number of parts are in the ENS name.
uint256 partsLength = ensNameParts.length;

// Concatenate each name part.
for (uint256 i = 1; i <= partsLength; i++) {
// Compute the handle.
// slither-disable-next-line encode-packed-collision
handle = string(abi.encodePacked(handle, ensNameParts[partsLength - i]));
handle = string(
abi.encodePacked(handle, ensNameParts[partsLength - i])
);

// Add a dot if this part isn't the last.
if (i < partsLength) handle = string(abi.encodePacked(handle, "."));
Expand All @@ -143,16 +164,25 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
/// @dev See https://eips.ethereum.org/EIPS/eip-137.
/// @param ensNameParts The parts of an ENS name to hash.
/// @return namehash The namehash for an ENS name parts.
function _namehash(string[] memory ensNameParts) internal pure returns (bytes32 namehash) {
function _namehash(
string[] memory ensNameParts
) internal pure returns (bytes32 namehash) {
// Hash the trailing "eth" suffix.
namehash = keccak256(abi.encodePacked(namehash, keccak256(abi.encodePacked("eth"))));
namehash = keccak256(
abi.encodePacked(namehash, keccak256(abi.encodePacked("eth")))
);

// Get a reference to the number of parts are in the ENS name.
uint256 nameLength = ensNameParts.length;

// Hash each part.
for (uint256 i; i < nameLength; i++) {
namehash = keccak256(abi.encodePacked(namehash, keccak256(abi.encodePacked(ensNameParts[i]))));
namehash = keccak256(
abi.encodePacked(
namehash,
keccak256(abi.encodePacked(ensNameParts[i]))
)
);
}
}

Expand All @@ -168,13 +198,6 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
return ERC2771Context._msgData();
}

//*********************************************************************//
// ---------------------------- constructor -------------------------- //
//*********************************************************************//

/// @param trustedForwarder The trusted forwarder for the ERC2771Context.
constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {}

//*********************************************************************//
// --------------------- external transactions ----------------------- //
//*********************************************************************//
Expand All @@ -185,7 +208,11 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
/// @param chainId The chain ID of the network the project is on.
/// @param projectId The ID of the project to set an ENS handle for.
/// @param parts The parts of the ENS domain to use as the project handle, excluding the trailing .eth.
function setEnsNamePartsFor(uint256 chainId, uint256 projectId, string[] memory parts) external override {
function setEnsNamePartsFor(
uint256 chainId,
uint256 projectId,
string[] memory parts
) external override {
// Get a reference to the number of parts are in the ENS name.
uint256 partsLength = parts.length;

Expand All @@ -202,6 +229,11 @@ contract JBProjectHandles is IJBProjectHandles, ERC2771Context {
// Store the parts.
_ensNamePartsOf[chainId][projectId][_msgSender()] = parts;

emit SetEnsNameParts({projectId: projectId, handle: _formatHandle(parts), parts: parts, caller: _msgSender()});
emit SetEnsNameParts({
projectId: projectId,
handle: _formatHandle(parts),
parts: parts,
caller: _msgSender()
});
}
}

0 comments on commit 2ca0059

Please sign in to comment.