There is not on-chain check that prevents users from minting handles on v2 that already exist on v1. This would prevent OG users of v1 from migrating their handles.
In order to stay true to the spirit of a decentralized social network, this check should be on-chain, and not depend on any possible off-chain list that the whitelisted profile creators, or the owner may have, as it could incomplete, with errors, or may not exist (as it is not mentioned).
Example 1: In the case a whitelisted profile creator does not keep an up to date list of the v1 profiles that should not be able to be minted, an adversary may choose a valuable Lens Handle name that hasn't been migrated.
Example 2: The contract owner can unknowingly provide a Lens Handle of an OG v1 user to another one.
This can't be undone without any upgrade.
Impact
Lens Handles represent part of the core user's identity on Lens Protocol v1. Users that own a Lens Handle on v1 should be expected to to migrate their handles to v2.
If other user mints their handle before they migrate it to v2, they will lose their right to own their corresponding handle on the new version of Lens.
The impact is permanent and can't be undone without any upgrade.
Proof of Concept
LensHandles::mintHandle() does not make any on-chain check to see if the v1 handle exists. If this function is called before migrateHandle(), the OG v1 user won't be able to migrate their handle:
function mintHandle(address to, string calldata localName)
external
onlyOwnerOrWhitelistedProfileCreator
returns (uint256)
{
_validateLocalName(localName);
return _mintHandle(to, localName);
}
function migrateHandle(address to, string calldata localName) external onlyHub returns (uint256) {
_validateLocalNameMigration(localName);
return _mintHandle(to, localName);
}
function _mintHandle(address to, string calldata localName) internal returns (uint256) {
uint256 tokenId = getTokenId(localName);
_mint(to, tokenId);
_localNames[tokenId] = localName;
emit HandlesEvents.HandleMinted(localName, NAMESPACE, tokenId, to, block.timestamp);
return tokenId;
}
Lines of code
https://github.com/code-423n4/2023-07-lens/blob/main/contracts/namespaces/LensHandles.sol#L87-L99 https://github.com/code-423n4/2023-07-lens/blob/main/contracts/namespaces/LensHandles.sol#L194-L200
Vulnerability details
Summary
There is not on-chain check that prevents users from minting handles on v2 that already exist on v1. This would prevent OG users of v1 from migrating their handles.
In order to stay true to the spirit of a decentralized social network, this check should be on-chain, and not depend on any possible off-chain list that the whitelisted profile creators, or the owner may have, as it could incomplete, with errors, or may not exist (as it is not mentioned).
Example 1: In the case a whitelisted profile creator does not keep an up to date list of the v1 profiles that should not be able to be minted, an adversary may choose a valuable Lens Handle name that hasn't been migrated.
Example 2: The contract owner can unknowingly provide a Lens Handle of an OG v1 user to another one.
This can't be undone without any upgrade.
Impact
Lens Handles represent part of the core user's identity on Lens Protocol v1. Users that own a Lens Handle on v1 should be expected to to migrate their handles to v2.
If other user mints their handle before they migrate it to v2, they will lose their right to own their corresponding handle on the new version of Lens.
The impact is permanent and can't be undone without any upgrade.
Proof of Concept
LensHandles::mintHandle()
does not make any on-chain check to see if the v1 handle exists. If this function is called beforemigrateHandle()
, the OG v1 user won't be able to migrate their handle:Tools Used
Manual Review
Recommended Mitigation Steps
Check for the existence of the corresponding Lens Handle on v1 before calling to mint it with the new
mintHandle()
function.Assessed type
Invalid Validation